经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Java java.lang.Thread#join()方法分析
来源:cnblogs  作者:justmehyp  时间:2018/11/22 10:26:07  对本文有异议

 

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

 

一、分析

查看源代码:

  1. public final void join() throws InterruptedException {
  2. join(0); //得接着看这个带参数的方法,这里传入 0 表示等待时间为永久
  3. }

带参数的 join:

  1. 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 挂掉的:

  1. while (isAlive()) {
  2. wait(0); //真正让线程 A 阻塞的是这个方法的调用
  3. }

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

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

 

 

二、应用场景

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

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

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

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号