下面为你整理一份 Thread.join() 方法(thread.join) 的“深入浅出讲解”,适用于 Java、多线程、面试准备,以及技术文章发布。


🌟 一、Thread.join() 是什么?

join() 是 Java 中 Thread 类提供的方法,用来让一个线程 等待另一个线程执行完毕

通俗理解:

A 线程调用 B 线程的 join(),表示:
A 要等 B 执行结束后才能继续往下走。


🧩 二、join() 的基本用法

示例代码:

Thread t = new Thread(() -> {
    System.out.println("子线程正在运行...");
});

t.start();    // 启动线程
t.join();     // 主线程等待 t 执行结束

System.out.println("主线程继续执行");

输出顺序保证:

子线程正在运行...
主线程继续执行


🎯 三、join 的作用(经典描述)

  • 让线程之间的执行按顺序进行
  • 避免线程抢占执行,保证业务流程一致性
  • 用于等待任务执行完毕后再做下一步

🛠 四、join 的三个重载方法

方法功能
join()一直等待,直到目标线程执行结束
join(long millis)最长等待 millis 毫秒
join(long millis, int nanos)毫秒 + 纳秒级等待

示例:

t.join(1000); // 最多等1秒

如果线程 1 秒内没结束,调用 join 的线程会继续执行。


⚙ 五、join 的底层原理(面试常问)

join() 的底层原理:

  • 内部调用了 wait() 方法。
  • 当目标线程执行完毕时,会自动 notifyAll() 唤醒等待的线程。

源码片段(简化):

public final void join() throws InterruptedException {
    synchronized (this) {
        while (isAlive()) {
            wait(0);  // 等待直到线程结束
        }
    }
}

关键点:

  • join 必须对线程对象上锁(synchronized(this))
  • 线程结束时 JVM 会自动调用 notifyAll()

所以本质上:

join = synchronized + wait + 线程结束后的 notifyAll


🧪 六、join 常见使用场景

✔ 1. 主线程等待子线程执行完

计算任务、文件下载、数据处理等需要“同步执行”。

✔ 2. 多线程执行后收集最终结果

比如统计任务、并行计算后汇总。

✔ 3. 限制线程执行顺序

确保 A → B → C 顺序执行。

✔ 4. 模拟串行效果(多线程按顺序调度)


🕹 七、三个线程必须顺序执行( join 经典案例 )

Thread t1 = new Thread(() -> System.out.println("1"));
Thread t2 = new Thread(() -> System.out.println("2"));
Thread t3 = new Thread(() -> System.out.println("3"));

t1.start();
t1.join();   // 等 t1

t2.start();
t2.join();   // 等 t2

t3.start();
t3.join();   // 等 t3

输出固定:

1
2
3


⚠ 八、join 使用注意事项(非常重要)

1. join 必须在 start() 之后

否则线程没有启动,join 会立即返回。

2. join 会阻塞当前线程

例如:

  • 主线程等子线程
  • 子线程等其他线程

要注意性能影响。

3. 避免死锁

例如两个线程互相 join:

A join B
B join A

→ 永远互相等待。

4. join 不能保证线程一定执行成功,只保证“执行结束”


📌 九、总结(极简版)

特性说明
作用让当前线程等待另一个线程结束
本质wait() + 线程结束事件通知
常用主线程等待子线程、多线程汇总结果
注意join 会阻塞、避免相互 join

如果你需要,我可以继续为你提供:

📌 Thread.sleep vs join 对比
📌 多线程详解(volatile、synchronized、Lock、Semaphore)
📌 Java 并发面试题 50 题
📌 join() 内部源码 + JVM 行为流程图

告诉我你想继续深入哪部分!