Java Thread join()方法源码分析及应用场景
时间:2018-11-21
本文章向大家介绍JAVA多线程 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 挂掉(计算结束),取得计算结果。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释