线程池本质是“任务提交→排队→调度→执行→回收”的闭环机制;其核心逻辑在execute()中,严格按“先试建核心线程→再入队→最后扩容非核心线程”顺序执行,依赖corepoolsize、maximumpoolsize、workqueue等参数协同决策。

Java 线程池的工作原理,本质是围绕“任务提交→排队→调度→执行→回收”这一闭环展开的。它不是简单地起个线程跑任务,而是通过一套状态判断与资源协调机制,动态决定任务由谁、何时、以何种方式执行。核心逻辑藏在 ThreadPoolExecutor.execute() 方法中,整个流程严格依赖五个参数的协同作用。
任务提交后,线程池怎么决定是否新建线程?
线程池收到任务的第一反应,不是看队列,而是先查当前活跃线程数:
- 如果 活动线程数 :不管有没有空闲线程,都立即创建一个新核心线程来执行该任务;
- 这个设计保证了核心线程能快速就位,也意味着即使已有4个核心线程空闲,第5个任务进来时若 corePoolSize=5,仍会新建第5个——直到凑齐核心线程数为止。
核心线程满了,任务去哪?队列怎么选才关键
当线程数已达 corePoolSize,新任务不再触发线程创建,而是尝试进入 workQueue:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 如果队列是
LinkedBlockingQueue(无界队列),任务几乎总能入队成功,但风险是内存可能被撑爆; - 如果队列是
ArrayBlockingQueue(有界队列),入队失败意味着队列已满,此时流程转向扩容判断; - 注意:哪怕队列里还有空位,只要线程数未达 maximumPoolSize,线程池也不会主动创建非核心线程——它只在队列塞不进时才考虑扩容。
队列满了,还能加线程吗?最大线程数不是摆设
只有当队列已满 且 当前线程数
- 这些线程是“临时工”,只在高负载时启用;
- 它们的存活时间由
keepAliveTime控制,空闲超时后自动销毁; - 一旦线程数达到 maximumPoolSize,再有任务进来且队列又满,就彻底没路可走了。
所有路都堵死了,拒绝策略怎么生效?
当 线程数 = maximumPoolSize 且 workQueue 已满,新任务触发拒绝策略 RejectedExecutionHandler:
-
AbortPolicy(默认):抛出RejectedExecutionException,调用方必须捕获处理; -
CallerRunsPolicy:由提交任务的线程自己执行该任务,可减缓提交速度; -
DiscardPolicy:静默丢弃,不报错也不执行; -
DiscardOldestPolicy:丢掉队列头的任务,腾位置给新任务。
任务最终交到 Worker 线程手上,线程会循环调用 queue.poll() 或 take() 取任务执行,执行完不退出,继续等下一个——这就是复用的本质。整个过程没有魔法,全是基于原子状态和队列特性的严谨判断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










