worker本质是继承aqs并实现runnable的“工作代理”,通过runworker()中的while循环持续领取执行任务(firsttask或gettask()),满足stop状态、队列空、超时或中断任一条件即退出,实现线程复用。

Worker 对象本质是可被线程反复执行的 Runnable
Worker 继承自 AQS,同时实现了 Runnable 接口。它不是一次性任务载体,而是长期驻留在线程池中的“工作代理”。当线程启动时,实际执行的是 Worker.run(),该方法内部直接调用 runWorker(this)。关键在于:这个 this 指向的是 Worker 实例本身,而 runWorker() 会持续驱动该 Worker 领取并执行任务,直到满足退出条件。
runWorker() 的核心循环:领任务 → 执行 → 清理 → 再领
runWorker(Worker w) 是整个工作线程生命周期的主干逻辑,其主体是一个 for 循环,形成“高频领任务”的底层闭环:
- 从队列中获取下一个任务(getTask()):可能阻塞(取决于 keepAliveTime 和队列类型),也可能立即返回 null(如线程池已 shutdown、worker 数超 corePoolSize 且空闲超时、或队列为空且无法创建新线程)
- 若 getTask() 返回非 null 任务,则执行 task.run():执行前会先调用 beforeExecute(),执行后调用 afterExecute(),异常时捕获并传给 afterExecute()
- 若 getTask() 返回 null,则跳出循环,进入 worker 清理流程:包括设置完成态、从 workers 集合中移除、更新线程池统计(completedTaskCount)、调用 terminated()
任务来源的三级优先级:当前 Worker 专属任务 > 阻塞队列 > 其他 Worker 的工作队列(work-stealing 不启用)
ThreadPoolExecutor 默认不启用窃取机制,因此每个 Worker 只从两个地方拿任务:
- Worker 自身初始化时携带的 firstTask(构造时指定):仅在首次循环执行,执行完即置为 null
- 全局 workQueue.take() 或 poll(timeout):后续所有任务均从此处获取,是高频领取的主路径;使用 LinkedBlockingQueue 时为阻塞式,使用 SynchronousQueue 时则依赖其他线程的 put 操作配对
注意:即使队列非空,若线程池处于 STOP 状态,getTask() 也会立即返回 null,强制 worker 退出。
退出闭环的四大触发条件
runWorker() 循环不会无限进行,以下任一条件满足即 break:
- 线程池状态 ≥ STOP(即 STOP 或 TERMINATED),不再接受任何任务
- 线程池状态为 SHUTDOWN,且 workQueue 已空(无待执行任务)
- getTask() 因 keepAliveTime 超时返回 null(适用于 allowCoreThreadTimeOut = true,或当前 worker 数 > corePoolSize)
- 线程被外部中断(且未忽略中断),且此时 getTask() 抛出 InterruptedException 或检测到中断位
一旦退出循环,worker 即结束生命周期,对应线程自然终止。
高频领取背后的性能设计:复用线程 + 减少创建销毁开销
所谓“高频”,本质是避免每次任务都新建线程。Worker 封装了线程与任务执行上下文(如 thread、firstTask、completedTasks 计数器),使得单个 Thread 对象可在整个生命周期内反复执行多个任务:
- 没有任务时,线程在 getTask() 中等待(park 或 timed wait),而非销毁
- 有任务到来时,唤醒即取即执,跳过线程创建/启动成本
- Worker 自身作为锁对象(AQS state 控制中断/运行态),保证执行过程的原子性与可见性
这种“线程不动、任务流动”的模型,正是线程池吞吐优势的底层根基。










