java中调用join()方法后当前线程进入waiting状态,因其底层基于object.wait()实现,释放锁并挂起等待目标线程终止,由jvm自动notifyall唤醒,不占用cpu且非blocked或timed_waiting(除非带超时)。

Java 中调用 join() 方法后,当前线程会进入 WAITING 状态(不是 BLOCKED,也不是 TIMED_WAITING,除非使用带超时的重载版本)。
这个状态是 JVM 线程生命周期中的标准状态之一,表示线程正在无限期等待另一个线程终止,且不占用 CPU 资源。
为什么是 WAITING 状态?
join() 方法底层通过 Object.wait() 实现,而 wait() 的语义就是让当前线程释放锁、挂起,并进入 WAITING 状态,直到被目标线程终止时 JVM 自动触发的 notifyAll() 唤醒。
- ✅ 调用
t.join()→ 当前线程进入 WAITING - ✅ 调用
t.join(5000)→ 当前线程进入 TIMED_WAITING(有超时) - ❌ 不会进入 BLOCKED:BLOCKED 是因争抢 synchronized 锁失败导致的,而
join()不涉及锁竞争 - ❌ 不是 RUNNABLE 或 TERMINATED:它已主动让出执行权,尚未结束
WAITING 状态的关键特征
- 线程暂停执行,不消耗 CPU
- 不持有任何 monitor 锁(
wait()会释放锁,但注意:join()同步的是目标线程对象本身,不是调用者的锁) - 只能被以下三种方式唤醒:
- 目标线程自然结束(JVM 自动调用
notifyAll()) - 当前线程被其他线程
interrupt()→ 抛出InterruptedException,并退出 WAITING - (仅对超时版本)等待时间耗尽 → 进入 RUNNABLE
- 目标线程自然结束(JVM 自动调用
常见误解澄清
-
join()不是“忙等”或轮询,不会持续检查线程状态 - 它不依赖
sleep(),所以和Thread.sleep()的阻塞机制完全不同 - 即使目标线程处于
WAITING/BLOCKED状态,只要还没终止,调用join()的线程就继续 WAITING
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











