
Java 线程池中的 Worker 类本身**并不直接继承 AQS**,而是**内部持有并组合使用 AQS 的一个子类(Worker 自定义的同步器)来实现任务执行状态的独占控制**——核心目的是保证每个 Worker 线程对自身所承载任务的“运行/中断/终止”状态变更具备原子性和排他性,而非用于线程间竞争任务队列。
Worker 与 AQS 的真实关系:组合而非继承
ThreadPoolExecutor.Worker 是一个继承自 AbstractQueuedSynchronizer 的**静态内部类**(注意:是 Worker 类自己继承 AQS,不是外部线程或线程池继承),它通过组合方式嵌入到 Worker 实例中,作为其状态同步的基础:
- Worker 类声明为
private final class Worker extends AbstractQueuedSynchronizer implements Runnable - 这意味着每个 Worker 对象既是可运行的任务(
Runnable),又是一个轻量级同步器(AQS 子类) - AQS 的 state 字段被重定义为 Worker 的运行状态:
0 表示未加锁(空闲/可被中断),
1 表示已加锁(正在执行任务,禁止中断)
为什么需要这个“独占锁”?关键在防止误中断
Worker 执行任务时,若线程正运行用户代码,此时调用 interrupt() 可能导致业务逻辑异常。JDK 通过 AQS 控制“是否允许中断”:
- 执行任务前,Worker 调用
acquire(1)—— 尝试将 state 从 0 设为 1;成功即获得“执行锁”,同时屏蔽中断 - 执行结束后,调用
release(1)—— 将 state 置回 0,恢复可中断状态 - 线程池在
interruptIdleWorkers()或 shutdown 过程中,只对 state == 0(空闲)的 Worker 调用interrupt(),避免打断正在运行的任务
核心方法如何基于 AQS 实现
Worker 重写了 AQS 的三个关键模板方法,构建极简独占语义:
-
tryAcquire(int unused):CAS 尝试将 state 从 0→1;失败说明已被占用(如其他线程正 tryAcquire 或任务已开始),返回 false -
tryRelease(int unused):直接设置 state = 0,无条件释放,因为 Worker 是单线程执行,不存在并发释放问题 -
isHeldExclusively():返回getState() == 1,用于断言当前线程是否持有该锁(例如在interruptIfStarted()中校验)
实际效果:一次只允许一个任务被“锁定执行”
这个 AQS 不用于排队、不涉及 Condition、也不参与线程竞争任务——它的全部使命就是为单个 Worker 提供一个线程安全的状态开关:
- 启动任务 → 加锁(state=1)→ 禁止中断 → 安全执行
- 任务结束/异常退出 → 解锁(state=0)→ 允许被中断 → 准备获取新任务或退出
- shutdownNow() 遍历 workers,对每个 worker 调用
interruptIfStarted(),该方法先检查isHeldExclusively(),仅当未加锁时才真正中断线程
这种设计精巧地复用了 AQS 的原子状态管理能力,以极低成本实现了 Worker 生命周期中关键临界区的独占控制,是典型的“小而准”的 AQS 应用范例。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











