java queue capacity,最近踩的一个线程池的坑: coreSize = 0 & queueCapacity > 1

最近踩了一个线程池的坑:

coreSize = 0, maxSize =4,

queueCapacity =1000  导致线程池并发为1,退化为单线程池。

提交第一个任务时,线程池发现当前poolSize不小于coreSize (都是0), 觉得没必要新建线程,就把任务置入队列;然后又发现当前池大小是0,于是新建一个线程,这个线程会来处理第一个任务。

在第一个任务执行完之前,提交第二个任务,线程池发现当前poolSize仍然不于小coreSize(1>=0),觉得没必要新建线程,也是于把任务置入队列;然后发现当前池大小不是0(是1),觉得没必要再新建线程了,于是结束submit()方法。

所以第一个任务不会马上执行,等池里唯一的线程执行完第一个任务后,才会来执行第二个任务。 就这样,多线程程序变成了单线程。 在队列被塞满之前,线程池都不会生成第二个线程,maxSize()设再高都没用。

从上也可以看出线程池中队列的作用:

当前有什么任务来不及处理,就“暂时”丢到队列里,等忙完手头上的事再去队列里捞出来处理;如果队列塞满了,才意识到自己人手不够,这时才要扩容线程(上限为maxSize)。

问题就在这里:“队列塞满才算人手不够”。 如果你的队列容量很大,虽然你只有一个线程,那你也不会觉得自己人手不够,因为队列总是塞不满。

所以,解决办法是,使用有界队列,让它能及时塞满, 然后提醒线程池扩容线程;或者也可以用SynchronousQueue,它是一种特殊的、容量为0的有界队列,或者严格地说,它根本不是队列,使用它,意味着不再“暂时”丢到队列里,而是直接交给空闲的线程,如果没有空闲线程就立即扩容。

回头一开始说的场景。如果poolSize改成2, 会怎么样? 显然,在queue被塞满之前,你只有两个线程干活,maxSize再大也没用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值