Java中线程处于WAITING状态只能由notify()/notifyAll()或unpark()显式唤醒:前者需同锁对象且唤醒后重竞争锁,后者基于许可机制;interrupt()不直接唤醒,仅触发异常或设置中断状态。

Java 中线程处于 WAITING 状态,必须由其他线程显式唤醒(不能靠时间自动超时,那是 TIMED_WAITING),核心方式只有两种:调用 notify() / notifyAll() 或 unpark()。
通过 synchronized + wait() 进入 WAITING,用 notify() 唤醒
这是最常见场景:线程在同步块中调用 Object.wait() 后进入 WAITING,它等待的是该对象的监视器锁(monitor)上的通知。
- 必须由**持有同一把锁的另一个线程**调用
notify()或notifyAll() - 被唤醒的线程不会立即执行,而是重新竞争该对象的锁;拿到锁后才从
wait()返回,继续向下执行 - 注意:
notify()只唤醒一个等待线程(不保证是哪一个),notifyAll()唤醒所有,更安全,避免信号丢失
通过 LockSupport.park() 进入 WAITING,用 unpark() 唤醒
使用 java.util.concurrent.locks.LockSupport 的 park() 方法会使线程进入 WAITING 状态(无超时版本),它等待的是一个与线程关联的“许可”(permit)。
- 任意线程都可以调用
LockSupport.unpark(targetThread)给目标线程发放许可,使其恢复运行 - 许可是二值的:有或没有。多次
unpark()等价于一次(不会叠加);如果线程尚未park(),许可会保留,后续park()直接返回 - 这是 AQS(如 ReentrantLock、Semaphore)底层唤醒机制的基础
不能靠 interrupt() 直接“唤醒” WAITING 线程
调用 thread.interrupt() 对纯 WAITING 线程(如刚进入 wait() 或 park())**不会立即改变其状态**,但效果不同:
立即学习“Java免费学习笔记(深入)”;
- 对
wait():中断本身不唤醒,但若线程在 wait 中被中断,会抛出InterruptedException并退出 wait —— 这本质是“被异常唤醒”,不是正常通知 - 对
park():中断不会抛异常,但会设置线程的中断状态;下次调用park()会直接返回(因已有许可或中断标记),但当前 park 不会因此返回 - 所以,interrupt() 不是唤醒 WAITING 的标准手段,而是协作式中断机制的一部分
常见误区提醒
以下操作无法让 WAITING 线程恢复执行:
- 调用
start()(线程已启动,无效) - 调用
resume()(已废弃且不生效) - 仅修改共享变量、发消息、写日志等(无通知语义)
- 在不同对象上调用
notify()(锁对象不匹配,唤醒失败)
关键记住:WAITING 是被动等待态,恢复执行依赖外部明确的通知动作 —— 要么锁对象发通知,要么 LockSupport 发许可。


















