Java 线程池核心原理:Worker 线程复用机制

发布时间:2026/5/22 7:51:36

Java 线程池核心原理:Worker 线程复用机制 大家好本篇我们来彻底讲透线程池最核心、最灵魂、面试最常问的知识点线程池是如何实现线程复用的很多同学会用线程池会写ThreadPoolExecutor也知道 7 大参数但你一旦被问线程执行完任务为什么不销毁为什么能接着执行下一个任务大部分人就答不上来了。答案只有一个因为线程池的线程根本不是普通 Thread而是 Worker本篇从原理到流程再到源码逻辑用最通俗的方式讲清楚让你彻底理解线程池的 “心脏”。一、先搞懂线程复用到底是什么意思我们先看不用线程池的情况new Thread(() - { // 任务执行 }).start();执行完 → 线程销毁。再来任务 → 再新建线程。创建 → 销毁 → 创建 → 销毁…开销巨大。线程池的线程复用线程执行完一个任务不销毁等着取下一个任务继续执行一直循环…这就是线程复用。那它是怎么做到不销毁、一直取任务的答案Worker 循环从阻塞队列 getTask ()二、线程池的真正工作者Worker 是什么ThreadPoolExecutor里面有一个内部类 Worker。它是线程池的 “工人”源码结构如下private final class Worker extends AbstractQueuedSynchronizer implements Runnable { final Thread thread; // 真正执行任务的线程 Runnable firstTask; // 第一个任务 Worker(Runnable firstTask) { this.firstTask firstTask; this.thread getThreadFactory().newThread(this); } public void run() { runWorker(this); // 真正执行逻辑 } }关键点Worker 本身是一个 Runnable它内部持有一个真正的Thread线程池的线程都是 Worker 里面的 thread线程复用就是 Worker 在复用一句话线程池 一堆 Worker 在不停循环干活。三、最核心方法runWorker ( ) —— 线程复用的灵魂线程池线程不销毁、能复用全靠这个方法final void runWorker(Worker w) { Runnable task w.firstTask; w.firstTask null; // 死循环 while (task ! null || (task getTask()) ! null) { // 执行任务 task.run(); // 执行完置空继续循环 task null; } }看到了吗一个 while 循环永远不退出流程先执行第一个任务执行完 → 调用getTask()去队列拿新任务拿到 → 继续执行再执行完 → 再去队列拿循环…这就是线程复用的本质线程不是执行完就死而是一直循环从队列取任务执行。四、getTask () 任务从哪来getTask()是决定线程 “什么时候活着、什么时候死亡” 的方法。它做两件事从阻塞队列 take /poll 任务控制核心线程 / 非核心线程的存活策略简化逻辑private Runnable getTask() { if (线程是核心线程 || 没超时) { // 一直阻塞等任务 return workQueue.take(); } else { // 非核心线程超时就返回null → 线程退出 return workQueue.poll(keepAliveTime, unit); } }重点核心线程 vs 非核心线程1核心线程workQueue.take()→队列空就一直等永远不退出→ 所以核心线程永远不销毁2非核心线程workQueue.poll(5, SECONDS)→ 等 5 秒还没任务→ 返回 null→ 循环退出→线程销毁这就是核心线程常驻非核心线程超时回收。五、完整流程线程从出生到死亡提交任务到线程池核心线程没满 → 创建WorkerWorker 内部创建 Thread并启动进入runWorker()的while 死循环执行任务执行完 → 调用getTask()去队列拿任务拿到 → 继续执行拿不到核心线程 →阻塞继续等非核心线程 →超时退出循环 → 线程销毁线程池 shutdown → 所有 Worker 被中断 → 全部销毁一句话总结Worker 死循环取任务 → 线程不销毁 → 实现复用六、为什么要设计 Worker不直接用 Thread你可能会问为什么不直接用 Thread非要搞个 Worker原因有 3 个1统一管理线程Worker 可以记录线程是否在执行任务是否可以被中断是否持有锁方便线程池管理。2实现 “可中断” 和 “优雅关闭”Worker 继承了 AQS可以安全中断、安全停止。3避免线程意外退出普通 Thread 执行完 run () 就退出。Worker 用 while 循环保证不退出。

相关新闻