核心线程与最大线程是“守备主力+应急增援”协作关系:先用核心线程,再填队列,队列满后才创建非核心线程;核心线程常驻不销毁,最大线程仅在队列满且核心忙时启用,超时回收;队列容量决定扩容时机。

核心线程和最大线程不是并列关系,而是“守备主力 + 应急增援”的协作结构。线程池不会因为任务一多就立刻拉满线程,它有明确的触发顺序:先用核心线程,再填队列,最后才动用最大线程的额度。
核心线程:永不下班的常驻员工
核心线程(corePoolSize)是线程池的底线配置。只要线程池没被关闭,这些线程就一直存活,哪怕空闲很久也不会自动销毁(除非显式开启 allowCoreThreadTimeOut)。它们承担日常稳定流量,是响应延迟最低、开销最可控的部分。
- 新任务提交时,线程池优先分配给空闲的核心线程执行
- 即使所有核心线程都忙,也不会立刻创建新线程——而是先把任务塞进队列
- 它的数量决定了线程池的“最小服务能力”,也是资源占用的基线
最大线程:只在队列满后才上岗的临时工
最大线程数(maximumPoolSize)不是“最多能开多少个线程”,而是“最多允许有多少个线程同时存在”。关键在于:它只在一种条件下被触发——核心线程全忙 + 任务队列已满。此时,线程池才会新建非核心线程来消化积压任务。
- 非核心线程创建后,如果空闲时间超过 keepAliveTime,就会被回收
- 一旦线程总数达到 maximumPoolSize,再有新任务且队列又满,就直接走拒绝策略
- 它本质是应对突发流量的弹性缓冲,不是常态运行目标
队列是核心与最大线程之间的“决策开关”
任务队列(workQueue)不是被动容器,而是控制线程扩容的关键闸门。它的容量大小,直接决定“什么时候启用最大线程”:
立即学习“Java免费学习笔记(深入)”;
- 用 ArrayBlockingQueue(10)(有界队列):队列填满第10个任务后,第11个任务若无空闲核心线程,就触发创建非核心线程
- 用 SynchronousQueue(无容量):相当于“不排队”,任务一来就尝试找空闲线程;没空闲就立即创建新线程(直到达 maximumPoolSize)
- 用 LinkedBlockingQueue(默认无界):几乎永远不触发最大线程扩容,容易掩盖问题、耗尽内存
典型协作流程(以 core=2, max=5, queue=3 为例)
提交8个任务,每个任务执行需2秒:
- 前2个任务 → 由2个核心线程立即执行
- 第3–5个任务 → 进入队列等待(占满3个位置)
- 第6个任务到达 → 队列已满,且核心线程仍在忙 → 创建第1个非核心线程执行
- 第7个任务 → 创建第2个非核心线程
- 第8个任务 → 创建第3个非核心线程(此时总线程数=5,已达 maximumPoolSize)
- 若再提交第9个任务,且队列仍满 → 触发拒绝策略(如抛出 RejectedExecutionException)

















