线程池的饱和策略-Semaphore实现任务提交限制

      java并发编程实践阅读笔记之线程池的使用  

      当线程池的工作队列被填满后,如果没有预定义的饱和策略来阻塞任务的执行,则可以通过信号量Semaphore来限制任务的到达率。Semaphore是一个同步工具类,用来控制同时访问某个特定资源的操作数量。它的acquire方法返回一个虚拟的许可,如果没有可用的许可,则阻塞该方法的调用线程直到有可用许可为止。如果线程池使用无界队列缓冲任务时,如果任务在某一时间增长数量过快,容易导致内存耗尽。

       无界队列和Semaphore搭配使用,通过设置信号量的上界,来控制任务的提交速率。使用上一章的MyCommand任务,结合Semaphore,代码如下:

/**
 * 
 * @title       :BoundedExecutor
 * @description :使用Semaphore控制任务的提交速率
 * @since       :2014-12-15
 */
public class BoundedExecutor {
	private final Executor exec;
	private final Semaphore semaphore;
	
	public BoundedExecutor(Executor exec,int bound){
		this.exec = exec;
		this.semaphore = new Semaphore(bound);
	}
	
	public void submitTask(final Runnable command) throws InterruptedException{
		try{
			semaphore.acquire();
			exec.execute(new Runnable(){
				@Override
				public void run() {
					try{
						command.run();
					}finally{
						System.out.println("执行完成 ,release...");
						semaphore.release();
					}
				}
			});
		}catch(RejectedExecutionException e){
			System.out.println("队列已满,拒绝执行");
			semaphore.release();
		}
	}
	
	public static void main(String[] args) {
		//虽然线程池大小为4,但是Semaphore限制每次只能有两个任务被执行
		Executor exec = Executors.newCachedThreadPool();
		BoundedExecutor b = new BoundedExecutor(exec,2);
		
		MyCommand c1 = new MyCommand("c1");
		MyCommand c2 = new MyCommand("c2");
		MyCommand c3 = new MyCommand("c3");
		MyCommand c4 = new MyCommand("c4");
		MyCommand c5 = new MyCommand("c5");
		try {
			b.submitTask(c1);
			b.submitTask(c2);
			b.submitTask(c3);
			b.submitTask(c4);
			b.submitTask(c5);
		} catch (InterruptedException execption) {
			execption.printStackTrace();
		}
	}
}

       任务执行结果:

pool-1-thread-2 ,name: c2,Mon Dec 15 16:20:17 CST 2014
pool-1-thread-1 ,name: c1,Mon Dec 15 16:20:17 CST 2014
执行完成 ,release...
执行完成 ,release...
pool-1-thread-1 ,name: c4,Mon Dec 15 16:20:22 CST 2014
pool-1-thread-3 ,name: c3,Mon Dec 15 16:20:22 CST 2014
执行完成 ,release...
执行完成 ,release...
pool-1-thread-1 ,name: c5,Mon Dec 15 16:20:27 CST 2014
执行完成 ,release...

     执行结果分析:使用Semaphore限制每次只能提交两个任务,任务完成后释放信号量许可,的确可以控制任务的提交速率。

你可能感兴趣的:(java,并发)