之前笔记有记录java线程池的拒绝策略,回顾一下线程池的处理任务的优先级:
先考虑corePoolSize、任务队列(缓冲队列)workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
即:
如果运行的线程少于corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队。(如果当前运行的线程小于corePoolSize,则任务根本不会存入queue中,而是直接运行)
如果运行的线程大于等于 corePoolSize,则 Executor始终首选将请求加入队列,而不添加新的线程。
如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝。
BlockingQueue <Runnable> workQueue 这个缓冲队列有三种类型:
1、直接提交SynchronousQueue
2、无界队列LinkedBlockingQueue
3、有界队列ArrayBlockingQueue
四种常用线程池:
1、newCachedThreadPool:内部使用SynchronousQueue
2、newFixedThreadPool:内部使用
3、newScheduledThreadPool:内部使用DelayedWorkQueue
4、newSingleThreadExecutor
(一般不要直接用包装好的,根据具体问题自行使用参数创建)
***问题:如果没达到核心线程的时候如果再有请求的时候为什么还会创建新线程?就算有空闲线程?
vimi说:“代码逻辑”
if(没满){ 新建 } else{ if(还有空闲){ 这时候才插入到空闲 } else{ 再去考虑加入队列以及拒绝策略 } }
参考:https://zhuanlan.zhihu.com/p/32867181