worker复用的本质是同一jvm线程对象和worker实例反复执行不同任务;其通过runworker中while循环持续从队列取任务,避免频繁创建销毁os线程。

线程池里的 Worker 不是每次任务都新建线程,而是让同一个 Worker 对象反复执行不同任务;而直接调用 Thread.start() 每次都会创建并启动一个全新的操作系统线程。
Worker 是怎么复用的
Worker 是 ThreadPoolExecutor 的内部类,它本身不是线程,但持有一个真实线程(thread 字段),并在构造时就绑定好。这个线程启动后,不会退出,而是循环从任务队列中取任务执行:
- Worker 启动后,会一直运行在自己的线程里,执行
runWorker(Worker w)方法 - 该方法内部是个 while 循环:先执行初始任务(
firstTask),再不断从阻塞队列(如workQueue)中take()或poll()新任务 - 只要队列有任务、线程没被中断、线程池没 shutdown,这个 Worker 就持续工作,不销毁也不重建
- 所以“复用”的本质,是同一个 JVM 线程对象 + 同一个 Worker 实例,反复承载不同
Runnable或Callable
Thread.start() 是一次性的系统级开销
每次调用 new Thread(runnable).start(),JVM 都会:
- 向操作系统申请资源,创建一个原生线程(native thread)
- 分配独立的栈内存(默认 1MB 左右)、程序计数器、寄存器上下文等
- 触发线程调度器将其加入就绪队列,等待 CPU 时间片
- 任务执行完后,线程终止,JVM 通知 OS 回收资源(包括栈、内核数据结构等)
- 整个过程涉及用户态/内核态切换,开销远高于纯 Java 对象操作
关键区别不在代码写法,而在生命周期管理主体
二者表面都“跑任务”,但控制权完全不同:
-
Thread.start():开发者全权负责线程的生老病死,每次都是独立生命周期 - Worker:生命周期由线程池统一托管。Worker 对象可被回收(比如空闲超时),但其内部线程不一定销毁——取决于是否允许核心线程超时(
allowCoreThreadTimeOut)或是否达到最大线程数限制 - Worker 还自带 AQS 锁(state = -1 初始化),用于控制中断状态,确保刚创建时不能被中断,体现的是线程池对执行安全的精细管控
- 真正被复用的,是那个底层的
Thread实例及其 OS 资源,Worker 只是它的“任务调度包装器”和“状态控制器”
举个直观对比
假设提交 100 个任务:
- 用 100 次
new Thread(...).start()→ 创建 100 个线程,至少经历 100 次创建+销毁 - 用
newFixedThreadPool(5)→ 最多 5 个 Worker,每个 Worker 的线程执行约 20 个任务,全程只创建 5 个线程,无销毁(除非 shutdown) - Worker 的“复用”不是魔法,而是把“创建线程→执行任务→销毁线程”这个串行闭环,拆成“创建线程(一次)→循环取任务→按需清理(可选)”的长生命周期模型
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











