object.wait()和thread.join()会使线程进入waiting状态,前提是无超时参数、未被中断且未被唤醒;前者需在synchronized块内调用并依赖notify,后者依赖目标线程终止时jvm自动notifyall。

Object.wait() 和 Thread.join() 确实会让当前线程进入 WAITING 状态,但“无条件永恒阻塞”这个说法需要谨慎——它们的阻塞不是绝对不可退出的,而是在没有外部干预时会一直等待下去。关键在于:是否设置了超时、是否被中断、以及唤醒机制是否触发。
Object.wait() 进入 WAITING 的明确条件
调用 obj.wait() 会让当前线程进入 WAITING 状态,前提是:
- 当前线程已持有
obj的监视器锁(即必须在synchronized(obj)块或方法内调用); - 调用的是无参版本
wait()或带零超时的wait(0); - 没有其他线程随后调用
obj.notify()或obj.notifyAll(); - 当前线程未被中断(否则抛
InterruptedException并退出 WAITING)。
满足以上四点,线程就会卡在 WAITING,直到被显式唤醒或中断。它不会因超时自动返回,这就是“看似永恒”的来源。
Thread.join() 进入 WAITING 的明确条件
thread.join()(无参)会让当前线程进入 WAITING 状态,当且仅当:
- 目标线程
thread尚未终止(thread.isAlive() == true); - 当前线程成功获取了
thread对象的内部锁(因为join()是synchronized方法); - 目标线程未结束,也未被中断(中断会提前抛出
InterruptedException); - JVM 在目标线程终止时自动调用其内部的
notifyAll()——但该唤醒对调用者是透明的,你无需、也不应手动调用。
只要目标线程还在运行,调用方就停在 WAITING;目标线程一结束,JVM 自动唤醒所有在它上面 wait 的线程。所以它的“永恒”是相对的,依赖于目标线程生命周期。
如何验证线程确实处于 WAITING 状态
可通过 Thread.getState() 实时观察:
- 在
wait()调用后、唤醒前打印状态,会输出WAITING; - 在
join()执行中、目标线程未结束前检查,状态也是WAITING(注意不是 BLOCKED); - 若用了
wait(1000)或join(1000),状态是TIMED_WAITING,不属于本题讨论的“无时限”情形。
真正“无法退出”的情况只有一种
既没被唤醒、也没被中断、目标线程又永不结束(比如死循环且不响应中断),此时 WAITING 状态将一直持续,直到 JVM 退出。但这不是 API 设计的缺陷,而是使用者未配合协作机制(如中断协议、合理终止逻辑)所致。










