线程池的饱和策略-调用者执行

      java并发编程实践阅读笔记之线程池的饱和策略

     使用java的任务管理框架的线程池执行任务时,线程池的任务等待队列被填满时,饱和策略开始发挥作用。ThreadPollExecutor的饱和策略通过setRejectedExecutionHandler来修改。JDK提供了4中饱和策略如下:

线程池的饱和策略-调用者执行_第1张图片

       AbortPolicy是默认的饱和策略,该策略会抛出未检查异常RejectedExecutionException,调用者可以捕获这个异常,然后根据自己的需求编写代码。CallerRunsPolicy则提供了一种调节机制,该策略不会抛弃任务,也不会抛出异常,而是将任务的运行回退到任务调用者,在提交任务的线程中执行该任务。下列例子中模拟了调用者运行策略,线程池初始化大小为2,等待队列大小为2,当提交任务大于4个时,第5个任务就会在任务提交的主线程中运行。

public class MyCommand implements Runnable {
	private String name;

	public MyCommand(String name){
		this.name = name;
	}
	
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+" ," +
				"name: "+name+","+new Date());
		try {
			Thread.sleep(5000);
		} catch (InterruptedException execption) {
			execption.printStackTrace();
		}
	}
}

       使用调用者运行策略执行任务:

public class CallerRunTest {
	private final ThreadPoolExecutor exec ;
	public CallerRunTest(){
		exec = new ThreadPoolExecutor(2,2,0L,TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<Runnable>(2));
		exec.setRejectedExecutionHandler(
				new ThreadPoolExecutor.CallerRunsPolicy());
	}
	
	public static void main(String[] args) {
		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");
		CallerRunTest c = new CallerRunTest();
		c.submit(c1);
		c.submit(c2);
		c.submit(c3);
		c.submit(c4);
		c.submit(c5);
	}

	public void submit(Runnable command){
		System.out.println(Thread.currentThread().getName()+" submit tast...");
		exec.submit(command);
	}
}

       提交的任务打印一句任务名称,然后休眠5秒,线程池大小为2,等待队列大小为2 ,当第5个任务提交时,它会在主线程中执行,其他任务则都是由线程池调度运行。运行结果如下:

main submit tast...
main submit tast...
main submit tast...
main submit tast...
main submit tast...
pool-1-thread-1 ,name: c1,Mon Dec 15 15:55:02 CST 2014
main ,name: c5,Mon Dec 15 15:55:02 CST 2014
pool-1-thread-2 ,name: c2,Mon Dec 15 15:55:02 CST 2014
pool-1-thread-1 ,name: c4,Mon Dec 15 15:55:07 CST 2014
pool-1-thread-2 ,name: c3,Mon Dec 15 15:55:07 CST 2014

      结论:调用者运行的饱和策略实现了一种调节机制,当工作队列被填满时,下一个待执行的任务会在任务提交主线程中执行,由于任务执行需要一定得时间,在任务运行期间主线程将不能再提交任务,以此可以降低任务的提交速率,为线程池正确更多的时间来完成正在排队的任务。

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