一、問題描述
在程序設計中,可能存在這樣的情景:主線程中存在一個子線程,子線程需要在執行完畢後爲後續代碼邏輯提供參數。但在代碼執行時,子進程還沒執行完畢,後續的代碼已經開始執行了,這時候就會出現參數爲空的異常,或是直接報錯。
public class ThreadTest {
public static void main(String[] args) {
String str;
Thread thread = null;
thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
System.out.println("Thread is running...");
break;
}
}
});
thread.start();
System.out.println("Thread is finished...");
}
}
執行結果:
因此,如何才能使得子進程執行完畢後纔開始運行後續代碼呢?
二、解決方法
1. join
Thread類提供了一個join( )方法,其原理是不斷檢查子進程是否執行完畢,當子進程未執行完成時,調用該子進程的進程被阻塞,直到子進程執行完畢後,再繼續運行調用進程。
public class ThreadTest {
public static void main(String[] args) {
String str;
Thread thread = null;
thread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
System.out.println("Thread is running...");
break;
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread is finished...");
}
}
執行結果:
2. CountDownLatch
CountDownLatch允許一個或多個線程等待其他線程執行完畢後再運行。
- CountDownLatch的構造函數接收int類型的參數作爲計數器,若要等待N個點再執行後續邏輯,就傳入N。
- 這裏的N可以是N個線程,也可以是N個執行步驟。
- 當我們調用countDown( )方法時,N會減一。
- 調用await( ) 方法來阻塞當前線程,直到N減爲0。
public class ThreadTest {
public static void main(String[] args) {
CountDownLatch count = new CountDownLatch(2);
String str;
Thread thread1, thread2 = null;
thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread1" + " is running...");
count.countDown();
System.out.println("Thread1 " + " is finished...");
}
});
thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread2" + " is running...");
count.countDown();
System.out.println("Thread2" + " is finished...");
}
});
thread1.start();
thread2.start();
try {
count.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All is finished.");
}
}
執行結果: