java join()源码_Java Thread join()方法源码分析及应用场景

结论:A 线程调用 B 线程对象的 join 方法,则 A 线程会被阻塞,直到 B 线程 挂掉 (Java Doc 原话: Watis for this thread to die)。

一、分析

查看源代码:

public final void join() throws InterruptedException {

join(0); //得接着看这个带参数的方法,这里传入 0 表示等待时间为永久

}

带参数的 join:

public final synchronized void join(long millis) // 注意这里的 synchronized  关键字,A 线程 获取了 B 线程对象的锁,所以下面的代码中才可以调用 wait 方法

throws InterruptedException {

long base = System.currentTimeMillis();

long now = 0;

if (millis < 0) {

throw new IllegalArgumentException("timeout value is negative");

}

if (millis == 0) { // 参数为 0

while (isAlive()) { // 等到死为止

wait(0); // 这是 Object 对象的 wait 方法,调用了这个方法的线程(A 线程)会阻塞

}

} else { // 等待参数指定的时间

while (isAlive()) {

long delay = millis - now;

if (delay <= 0) {

break;

}

wait(delay);

now = System.currentTimeMillis() - base;

}

}

}

到这里,基本可以得出开头的结论了。

但是,开头的结论并不十分严谨,因为线程 A 其实并不是一直阻塞直到线程 B 挂掉的:

while(isAlive()) {

wait(0); //真正让线程 A 阻塞的是这个方法的调用

}

当 进入 wait(0) 时,线程 A 阻塞,但 wait(0) 返回时,线程 A 唤醒,但是 while 循环条件如果满足的话 (线程 B 还没死),线程 A 再次阻塞。

线程 A 一直在 join 方法里,在阻塞和唤醒之间不断切换状态,直到线程 B 挂掉。

二、应用场景

为什么要让线程 A 阻塞,直到线程 B 挂掉呢?

假如:线程 B 在做一个耗时的计算,线程 A 需要这个计算的结果,并且线程 A 没有其他事要做了,只想得到计算结果,那么线程 A 就可以 调用线程 B 对象 的 join 方法,

让自己阻塞,等线程 B 挂掉(计算结束),取得计算结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`join()` 方法是 `Thread` 类中的一个方法,它的作用是让调用该方法的线程等待该线程执行完毕。当一个线程使用 `join()` 方法时,调用线程会被阻塞,直到被调用线程执行完毕后才会继续执行。 下面是 `join()` 方法源码: ``` public final void join() throws InterruptedException { join(0); } ``` 可以看到,`join()` 方法实际上是调用了另一个重载方法 `join(long millis)`,并将参数设置为 0。 ``` 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; } } } ``` 可以看到,`join(long millis)` 方法是一个同步方法,它首先对传入的参数进行检查,如果小于 0,则会抛出异常。 如果传入的参数为 0,则调用 `wait(0)` 方法,这会使当前线程进入等待状态,直到被调用线程执行完毕后才会被唤醒。 如果传入的参数不为 0,则会在循环中检查被调用线程是否还活着,如果还活着,则调用 `wait(delay)` 方法,这会使当前线程进入等待状态,等待一定的时间后被唤醒。在每次循环中,都会更新当前时间 `now`,并计算需要等待的时间 `delay`。 如果被调用线程已经执行完毕或者等待时间已经超过了传入的参数,则会跳出循环,方法执行完毕。 总的来说,`join()` 方法的本质是利用了 `wait()` 和 `notify()` 方法实现线程的同步和等待。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值