1. 作用
场景:把执行线程加入到当前线程,可以实现将两个交替执行的线程合并为顺序执行的线程。
例如:A线程中调用B线程的join()方法,从调用的位置开始知道B线程执行完成才会继续执行A线程。
2. demo
我们定义main方法为主线程;Thread对象创建的线程为子线程
class Test{
// 定义main方法为主线程
public static void main(String args[])throws InterruptedException{
Thread t=new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.print("2");
}
});
t.start();
// 在主线程中加入子线程
t.join();
System.out.print("1");
}
}
解析:当子线程执行完成后即控制台输出2后再执行子线程即控制台输出1;所以结果为:21。
3. 源码解析
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis)
throws InterruptedException {
// 获取join方法被调用时的时间戳,用于计算当前时间
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,则join方法不会生效
while (isAlive()) {
wait(0);
}
} else {
// 通过isAlive方法判断线程是否终止,终止或未启动时返回false,则join方法不会生效
while (isAlive()) {
// 计算剩余等待时间
long delay = millis - now;
// 如果剩余等待时间小于等于0则跳出等待
if (delay <= 0) {
break;
}
// 等待指定时间
wait(delay);
// 计算当前时间
now = System.currentTimeMillis() - base;
}
}
}
// 判断线程是否终止,本地方法
public final native boolean isAlive();
// 等待的方法
public final native void wait(long timeout) throws InterruptedException;