应用场景
在java中,等待另外一个线程执行完毕后,再执行,那就得用join方法了。
比如,需要使用线程A的结果,所以必须等待线程A执行完毕后,再继续执行。
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("自定义线程执行结束");
}
});
t.start();
//等待线程t执行完毕后,再继续执行
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程运行结束");
// 执行结果是确定的,先执行t,再执行主线程
自定义线程执行结束
主线程运行结束
原理
查看join源码可知,join()=wait(0),让当前线程无限期等待;t.join()时,会让当前线程Main进入waiting状态,并释放对象监视器t;等t执行完毕后,销毁时(这部分在native代码里),会唤醒对象t上的所有等待线程,从而使主线程继续执行;
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;
}
}
}
join vs sleep
join是Thread的实例方法,执行后,当前线程进入WAITING/TIMED_WAITING状态,会释放对象监视器;
sleep是Thread的静态方法,执行后,当前线程也会进入WAITING/TIMED_WAITING状态,但它不会释放对象监视器;