Thread.join():join()的作用是“等待该进程终止”,也就是在子线程调用了join()方法后,主线程后面的代码要等到子线程结束了才能执行。一般应用于一个线程的输入可能依赖于另一个或者多个线程的输出,此时这个线程就需要等待依赖线程执行完毕才能继续执行。
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
从源码分析join方法:
(1)join():表示无限等待,它会一直阻塞当前线程,至到目标线程执行完毕
public final void join() throws InterruptedException {
join(0);
}
(2)join(long millis, int nanos):表示等待目标线程终止时间最长为millis毫秒+nanos纳秒
public final synchronized void join(long millis, int nanos) throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException( "nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
(2)join(long millis):表示如果超过规定的时间目标现成还在执行,当前线程也会因为“等不及了”,而继续往下执行
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); //当前线程进入wait状态
now = System.currentTimeMillis() - base;
}
}
}
从源码可以看出:
join()方法的实现还是调用的join(long millis)方法,传参是0,如果millis等于0,则通过isAlive()判断目标线程的状态,如果当前的状态是“活”的,说明目标线程还未执行完成,当前线程进入wait状态,直到目标线程执行完毕,isAlive()返回false。如果millis大于0,也是循环判断目标线程状态,如果当前状态是“活”的,则判断是否已到规定时间,如果已到规定时间则break结束,当前线程不会再等待目标线程而继续往下执行,如果没有到底规定时间则进入wait状态
eg:
写一个简单的例子来看一下join()的用法:
public class JoinThreadTest {
public volatile static int i = 0;
public static class AddThread extends Thread{
@Override
public void run() {
for (i = 0; i < 100000; i++);
}
}
public static void main(String[] args) {
AddThread addThread = new AddThread();
addThread.start();
try {
addThread.join();
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
打印结果:
100000
修改一下代码:
public class JoinThreadTest {
public volatile static int i = 0;
public static class AddThread extends Thread{
@Override
public void run() {
for (i = 0; i < 100000; i++);
}
}
public static void main(String[] args) {
AddThread addThread = new AddThread();
addThread.start();
System.out.println(i);
}
}
返回结果:
0 或者一个非常小的数字