线程的join方法


基本概念


  • join()​ 定义在​Thread.java​中
  • join()​ 的作用 ​: 让主线程等待子线程结束之后才能继续运行

join源码

/**
* 等待millis毫秒后线程结束.如果值为0则表示永久等待
*
* 该实现使用循环的wait调用条件为isAlive的方法
* 当一个线程结束时会调用notifyAll方法
* 建议不要在线程实例上使用wait,notify和notifyAll方法
*
* @param millis 以毫秒级的时间等待
* @throws IllegalArgumentException 当millis的值不合法时抛出异常
* @throws InterruptedException 当线程被中断时抛出异常
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;

if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

  • 当​millis == 0​时,会进入​while(isAlive())​ 循环.只要子线程是活的,主线程就会不停的等待
  • 问题:​ 虽然​s.join()​ 被调用的地方是在主线程中,但是​s.join()​ 是通过子线程​s​调用的​s.join().​ 那么​join()​ 方法中的​isAlive()​ 应该是判断子线程​s​是不是​Alive​状态.对应的​wait(0)​ 应该是让子线程​s​等待才对? 这样​s.join()​ 的作用为什么会是让主线程等待直到子线程完成为止呢?

  • wait()​ 的作用是让 ​[当前线程]​ 等待
  • 这里的 ​[当前线程]​ 是指当前在CPU上运行的线程
  • 虽然调用的是子线程的​wait()​ 方法,但是是通过主线程去调用的.所以休眠的是主线程而不是子线程


join运行流程

Java多线程Day08-多线程之线程join()方法_java


  • 在主线程​main​中通过​new ThreadA(“t1”)​ 新建线程​t1
  • 通过​t1.start()​ 启动线程​t1,​ 并执行​t1.join()
  • 执行​t1.join()​ 之后,主线程​main​进入 ​[阻塞状态],​ 等待​t1​运行结束
  • 子线程​t1​结束之后,会唤醒主线程​main,​ 主线程重新获取​CPU​执行权,继续运行