JDK中的线程池(ThreadPoolExecutor)

本文详细介绍了线程池的三种执行策略及其应用场景:有界队列、无界队列和直接提交,并讨论了CallerRunsPolicy策略下线程池的运作机制与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.ThreadPoolExecutor =>
线程池在启动后,不管有没有任务来时,就会先创建coreSize个线程数。

(1)、使用有界队列(ArrayBlockingQueue):=>maxPoolSize和队列大小需要平衡。
当要执行的任务数小于coreSize时,就用coreSize个线程执行任务,
当任务数等于coreSize的大小时,新来一个任务,则首先将任务放入队列中,以此类推,直到队列满;
当队列满时,再新来一个任务,则新开一个线程,以此类推,直到达到线程池的最大值。
当队列满并且最大线程数到达时,再新来一个任务,执行拒绝策略。
/////////begin//////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 25, 1000, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(70),new ThreadPoolExecutor.CallerRunsPolicy());
////////end/////////
(2)、使用无界队列(LinkedBlockingQueue):=>maxPoolSize失效
当要执行的任务数小于coreSize时,就用coreSize个线程执行任务,
当任务数等于coreSize的大小时,新来一个任务,则新开一个线程,以此类推,直到队列满(如果队列的size无限大,则不会满)。
/////////begin///////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 25, 1000, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(Integer.MAX_VALUE),new ThreadPoolExecutor.CallerRunsPolicy());
/////////end/////////
(3)、使用直接提交(SynchronousQueue):=>
当有任务来时,总是开启新线程来执行任务。因此,建议maxPoolSize要足够大,否则会丢弃任务。
////////begin////////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 1000, TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),new ThreadPoolExecutor.CallerRunsPolicy());
//////////end////////

结论:使用有界队列和CallerRunsPolicy 保证线程池的可伸缩性。比如:
////////begin///////
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 30, 1000, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.CallerRunsPolicy());
///////////end//////
注意:【jdk线程池的bug】目前jdk6及之前的版本有bug,需要使用jdk7之后的版本。参见:
【http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458662】

注意:CallerRunsPolicy策略
==>A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method

关于【CallerRunsPolicy】,如果线程main中调用了线程池方法,如:executor.submit()或者executor.execute(),那么当线程池以最大线程在运行并且排队队列也变满时,
此时再进来一个任务的情况下,该任务就执行CallerRunsPolicy策略的语义(字面义也是调用者运行的意思),即让调用线程池的调用者来运行该任务,当此任务执行时间比较长时,会出现
线程池中的线程已空闲,但是调用者线程还没有执行完长任务时,再来新任务就不会被加入线程池中,直到调用者线程执行完毕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值