线程池本质是「有纪律的工人调度系统」:先用核心线程处理任务;核心忙则入队等待;队满且未达最大线程数时扩容非核心线程;否则触发拒绝策略;全程由ctl原子变量无锁管控状态与数量。

直接讲清楚线程池在干什么,比背参数更有说服力。它本质就是一个「有纪律的工人调度系统」:提前招好一批固定人手(核心线程),活来了先派他们干;人手不够就让任务排队(阻塞队列);队排满了再临时加人(非核心线程);人太多或活太忙就拒掉新任务(拒绝策略)。整个过程由一个原子变量 ctl 统一管着状态和人数,不加锁也能安全切换。
线程池怎么决定“要不要新建线程”
每次调用 execute() 提交任务时,线程池按三步走:
- 如果当前线程数
- 否则尝试把任务塞进 workQueue;成功了就等空闲线程来取,失败了说明队列已满
- 队列满且线程数
线程是怎么被复用起来的
关键在 Worker 类——它不是普通线程,而是实现了 Runnable 的工作单元:
- 每个 Worker 持有一个真实 Thread 对象和一个初始任务(firstTask)
- 启动后执行 runWorker(),先干 firstTask,再循环调用 getTask() 从队列里持续取新任务
- getTask() 会阻塞等待,直到有任务或超时退出;非核心线程超时后自动销毁,核心线程默认一直等着
线程池的状态不是摆设,是真正在控场
ctl 这个整数高 3 位存状态,低 29 位存线程数,一次 CAS 就能同时更新两个维度:
- RUNNING:接受新任务 + 处理队列里的任务
- SHUTDOWN:不接新任务,但继续处理队列和进行中的任务(shutdown() 触发)
- STOP:不接新任务、不处理队列、中断所有进行中的任务(shutdownNow() 触发)
- TIDYING 和 TERMINATED 是收尾阶段,用于回调 terminated()
队列选错,线程池就容易“假死”或“爆内存”
workQueue 不只是容器,它直接影响扩容逻辑和资源表现:
- SynchronousQueue:无容量,任务必须立刻交给线程,否则就新建线程 → 适合短平快任务,易扩到 maximumPoolSize
- LinkedBlockingQueue:默认无界,看似安全,但任务积压会吃光内存 → 生产必须设容量上限
- ArrayBlockingQueue:有界,配合拒绝策略更可控,适合对响应时间敏感的场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











