Thread.join()方法介绍
join()是Thread的一个方法,是等待该线程终止。将调用线程挂起,等待其执行完成。
当调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。
Thread.join()使用场景
- 线程A\B\C 顺序执行
- 主线程创建子线程,子线程执行时间长大于主线程执行时间。如果主线程需要知道子线程结束的结果时,join()是个比较好的场景
Thread.join 提供3个重载的方法
- 3个都是final修饰符,无法被修改
- join()等价于join(0)
- join(大于0)表示会等待一段时间
public final void join() throws InterruptedException;
public final synchronized void join(long millis) throws InterruptedException;
public final synchronized void join(long millis, int nanos) throws InterruptedException;
Thread.join()源码分析
/**
* Waits for this thread to die. 等待此线程结束
*/
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis) throws InterruptedException {
//获取当前时间
long base = System.currentTimeMillis();
long now = 0;
//等待时间小于0会抛出异常IllegalArgumentException
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
//不加参数的调用,默认时间为0,会无线等待下去
if (millis == 0) {
//isAlive本地方法,线程未启动或结束会返回false
while (isAlive()) {
wait(0);
}
} else {
//添加参数调用
while (isAlive()) {
//算出还需要等待的时间
long delay = millis - now;
//如果等待时间小于等于0,则退出等待
if (delay <= 0) {
break;
}
//继续等待
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
Thread.join() 让线程A 线程B 线程C 顺序执行
package lock;
import java.util.Random;
/**
* @Author: javanull on 2021/9/7.
*/
public class JoinDemo {
public static void main(String[] args) {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("threadA运行");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
//threadB调用threadA的join方法,threadB会等待threadA运行完之后才会开始执行后续代码
try {
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("threadB运行");
}
});
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
//threadC调用threadB的join方法,threadC会等threadB运行完之后才会开始执行后续代码
try {
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("threadC运行");
}
});
threadA.start();
threadB.start();
threadC.start();
}
}
结果
threadA运行
threadB运行
threadC运行