join()方法使当前线程阻塞等待目标线程终止,底层基于目标线程对象的wait()/notifyAll()机制实现:调用时获取其锁、检查isAlive()、存活则wait释放锁,JVM在线程终结时自动notifyAll唤醒。

Java 中的 join() 方法可以让主线程(或任意线程)**阻塞等待**指定子线程执行完毕后再继续运行,底层基于 wait() 机制实现,无需手动加锁或轮询。
join 的基本用法
调用子线程对象的 join() 方法,当前线程就会暂停,直到该子线程结束:
-
thread.join():无限等待,直到子线程终止 -
thread.join(5000):最多等待 5 秒,超时后继续执行(即使子线程还没结束) -
thread.join(5000, 500000):更精确的纳秒级等待(一般用不到)
典型使用场景示例
比如主线程要等多个子线程完成数据处理再汇总结果:
Thread t1 = new Thread(() -> { /* 耗时任务1 */ });
Thread t2 = new Thread(() -> { /* 耗时任务2 */ });
<p>t1.start();
t2.start();</p><p>try {
t1.join(); // 主线程在此等待 t1 结束
t2.join(); // 再等待 t2 结束
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
}</p><p>System.out.println("所有子线程已完成,开始汇总");
join 的底层原理简析
join() 并不是简单地循环检查 isAlive(),而是通过对象监视器(monitor)配合 wait() 实现的:
立即学习“Java免费学习笔记(深入)”;
- 每个
Thread对象内部有一个私有锁(this),子线程结束前会自动调用notifyAll() -
join()在该锁上执行wait(),释放锁并进入等待队列 - 子线程执行完
run()后,JVM 自动唤醒所有在该线程对象上等待的线程
注意事项和常见误区
使用 join() 时要注意以下几点:
- 必须在子线程
start()之后调用join(),否则无效(甚至抛出IllegalThreadStateException) -
join()可被中断,需捕获InterruptedException并合理处理 - 不要在子线程中对自身调用
join()(会导致死锁) - 若想“批量等待”,可把线程存入集合,遍历调用
join(),无需额外同步


















