threadpoolexecutor处理新任务遵循核心线程优先→队列缓冲→非核心线程兜底→拒绝策略的四级流程:先尝试创建核心线程执行;若核心线程满则入队等待;队列满且线程数未达maximumpoolsize时创建非核心线程;否则触发拒绝策略。

ThreadPoolExecutor 处理一个新任务时,并不是按“先排队、再开线程”的直觉顺序,而是严格遵循核心线程优先创建 → 队列缓冲 → 非核心线程兜底的三级决策链。这个流程由 execute() 方法驱动,每一步都带状态检查和原子操作保障。
第一步:尝试用核心线程立即执行
提交任务后,线程池首先检查当前工作线程数是否小于 corePoolSize:
- 如果是,不管有没有空闲核心线程,都会调用
addWorker(command, true)创建一个新核心线程并直接执行该任务; - 这一步不经过队列,任务“秒级”进入运行态;
- 哪怕已有 4 个核心线程在空闲,第 5 个任务仍会触发第 5 个核心线程创建(直到达到
corePoolSize)。
第二步:队列缓冲,等待空闲线程取走
当核心线程已满(workerCount ≥ corePoolSize),线程池转向任务队列:
- 若队列未满(
workQueue.offer(command)返回true),任务入队,不创建新线程; - 此时任务处于“待命”状态,由任意空闲线程(包括刚完成任务的核心线程)从队列中
take()执行; - 注意:队列是否“满”,取决于具体实现——
LinkedBlockingQueue默认无界,ArrayBlockingQueue有固定容量,SynchronousQueue容量为 0(即不缓存,直接要求有线程立刻接手)。
第三步:扩容非核心线程执行
队列已满且仍有新任务提交时,进入扩容判断:
- 若当前线程总数
,调用 <code>addWorker(command, false)创建非核心线程执行该任务; - 非核心线程启动后只负责当前任务,执行完若空闲超过
keepAliveTime就会被回收; - 这个阶段的任务不进队列,是“绕过缓冲区”的即时处理,用于应对突发流量。
第四步:拒绝策略兜底
当以上三步全部失败(队列满 + 线程已达 maximumPoolSize),说明系统已饱和:
- 线程池调用预设的
RejectedExecutionHandler; - 默认是
AbortPolicy(抛RejectedExecutionException); - 其他常见策略如
CallerRunsPolicy(让提交线程自己执行)、DiscardOldestPolicy(踢掉队首任务腾位)等,都是在此刻生效。
整个流转不是轮询或随机调度,而是一次性决策:每个任务只经历其中一条路径,不会“先入队再被非核心线程抢走”。理解这点,才能合理设置 corePoolSize、队列类型和 maximumPoolSize 的组合。










