應用場景
在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狀態,但它不會釋放對象監視器;