1.用法讲解
Join()是Thread的一个方法,会使得执行该代码的线程(通常为主线程)处于跟随状态,只有对象线程执行完后,主线程才会执行。
public class ThreadJoinClass {
private volatile static int i = 0;
private static class AddThread extends Thread {
@Override
public void run() {
for (i = 0; i < 10000; i++) ;
}
}
public static void main(String[] args) throws InterruptedException {
AddThread t = new AddThread();
t.start();
t.join(); //主线程调用了这个,使得主线程跟随t之后执行.
System.out.println("i: " + i);
}
}
如上代码,t.join()是在主线程中调用的,故主线程处于跟随状态,在t执行完后,主线程才会输出i:10000。
一句话概括就是:谁调用谁跟随。跟随的对象线程是谁呢,就是调用join()方法的对象。
2.原理
查看其源码,join()是通过调用对象的wait来实现的。比如主线程调用了 t 线程的join()方法,实际上是调用 t 线程的wait()方法,阻塞自己,然后释放 t 对象的锁,使得 t 线程执行,在 t 执行完后,会通过notifyAll()方法,唤醒主线程去执行。
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);
now = System.currentTimeMillis() - base;
}
}
}
上面的代码为Thread里join()方法的源码,很清楚的看到会调用 t (线程)对象的wait()方法,使得主线程处理阻塞状态。当 t 执行完后,会通过notifyAll()方法唤醒其他线程。