Java线程池Worker类用不可重入锁绑定锁状态与执行状态:构造时state=-1防早中断,runWorker中lock()设state=1表忙碌,仅state=0时interruptIdleWorkers才成功中断;getTask()阻塞时可被唤醒并判空退出,中断仅作唤醒触发器而非业务判断依据。

Java线程池中Worker类用不可重入锁防止中断正在运行的任务,核心在于“锁状态 = 执行状态”的绑定逻辑。它不靠屏蔽中断信号,而是通过AQS的tryLock机制让中断操作失败,从而自然规避误中断。
锁状态直接反映任务执行状态
Worker继承AbstractQueuedSynchronizer(AQS),将同步状态state设为-1(初始未启动)、0(空闲)、1(已加锁)。关键点是:
– 构造时setState(-1),防止线程还没start就被interrupt;
– runWorker方法真正开始执行firstTask前,调用lock()将state设为1;
– 只要state == 1,就表示该Worker正忙于执行一个任务,此时任何外部中断请求都必须先获取锁——而tryLock()会失败。
中断只对空闲线程生效
线程池调用shutdown、setCorePoolSize等方法时,会触发interruptIdleWorkers(),其内部遍历所有Worker并执行:
- worker.tryLock() → 成功才说明state == 0(空闲),接着调用thread.interrupt()
- 若worker已加锁(state == 1),tryLock()返回false,中断被跳过
- getTask()阻塞在workQueue.take()时,线程处于WAITING状态,且未持锁(state == 0),此时interrupt能唤醒它,后续检查队列为空就退出
不可重入性杜绝了“锁内再中断自己”的风险
如果Worker用的是可重入锁(如ReentrantLock),那么在调用setCorePoolSize等管理方法时,主线程可能在已持锁状态下再次尝试加锁成功,进而错误地中断正在执行任务的worker线程。不可重入设计确保:
- 同一个Worker线程无法重复lock(),避免执行中被自己或管理逻辑干扰
- 主线程调用interruptIdleWorkers时,仅凭一次tryLock就能准确区分“忙”与“闲”
- 任务执行期间,中断标志位可能被设置,但runWorker循环里不会响应——因为interrupted()检查只在getTask()前后做,而那时线程已解锁
实际中断流程是“唤醒 + 判空 + 退出”三步
被中断的线程并不会立刻停止。它被唤醒后会回到runWorker循环,再次调用getTask()。此时:
立即学习“Java免费学习笔记(深入)”;
- 若workQueue非空,继续取任务执行(中断被忽略)
- 若workQueue为空,且满足线程回收条件(如allowCoreThreadTimeOut或线程数超max),getTask()返回null,循环结束,线程自然终止
- 整个过程不依赖中断信号做业务判断,只用它作为“从阻塞中出来看看要不要走”的触发器

















