下面是join()的底层代码
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;
}
}
}
执行过程:在线程A内部调用线程B的join()函数时,会暂停A线程,等线程B执行结束后才会结束暂停。如果调用的join带有时间参数,则时间计时结束也会结束wait()过程。
理解
isAlive的对象是调用join的对象(即B),则此方法判定线程B是否存活(就绪状态或者运行状态)
wait()的对象是当前线程(即A),则此方法使得正在执行的线程A休眠(即跳过其执行过程)
下面举个例子
设置两个线程类 ,并在一个子线程中调用另一个线程的join方法。
public class Thread1 extends Thread {
public Thread1(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":"+i);
}
}
}
public class Thread2 extends Thread {
public Thread2(String name) {
super(name);
}
@Override
public void run() {
Thread1 B = new Thread1("B");
B.start();
try {
B.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":"+i);
}
}
}
在主类中按一定次序启用线程
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread2 A = new Thread2("A");
Thread1 C = new Thread1("C");
Thread1 D = new Thread1("D");
Thread1 E = new Thread1("E");
C.start();
A.start();
D.start();
D.join();
E.start();
}
}
获得结果如下
理解
调用A线程时,会在A中启用B的join方法时,致使A线程暂停。但并未影响到主线程,主线程仍然向后运行并开启了D。
主线程中启用D的join方法后,则暂停执行,即E暂时无法start,但不会影响到其他线程。