等待執行緒結束
等待執行緒結束
在某些時候,我們需要等待執行緒執行結束(run()方法結束其執行)。例如,在開始其他任務執行之前,程式首先要初始化所需資源。我們可以用執行緒來初始化任務,直到初始化結束後,再執行程式的後續任務。
通過使用Thread類中的join()方法,可以達到此目的。當使用執行緒物件呼叫join()方法時,它延緩執行此執行緒,直到物件執行結束。
在本節中,通過一個初始化範例學習使用這個方法。
準備工作
本範例通過Eclipse開發工具實現。如果使用諸如NetBeans的開發工具,開啟並建立一個新的Java專案。
實現過程
通過如下步驟完成範例:
-
建立DataSourcesLoader類,指定其實現Runnable介面:
public class DataSourcesLoader implements Runnable {
-
實現run()方法。通過輸出一條表明其開始執行的資訊,休眠4秒鐘後,再輸出一條表明結束執行的資訊:
@Override public void run() { System.out.printf("Beginning data sources loading: %s\n", new Date()); try { TimeUnit.
-
建立NetworkConnectionsLoader類,指定其實現Runnable介面。實現run()方法,內容與DataSourcesLoader類相同,但是休眠時間為6秒鐘 。
-
現在實現主類,包含main()方法的Main類:
public class
-
建立DataSourcesLoader類的物件以及執行此物件的執行緒:
DataSourcesLoader dsLoader = new DataSourcesLoader(); Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
-
建立NetworkConnectionsLoader類的物件以及執行此物件的執行緒:
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader(); Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
-
呼叫start()方法執行兩個執行緒:
thread1.start(); thread2.start();
-
使用join()方法等待兩個執行緒執行結束。這個方法能夠丟擲InterruptedException異常,所以我們使用程式碼捕獲它:
try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
-
在控制檯中輸出表明程式結束的資訊:
System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
-
執行程式,檢視結果。
工作原理
當執行範例時,需要理解兩個執行緒物件如何開始執行的。首先DataSourcesLoader執行緒執行結束,然後NetworkConnectionsLoader類執行完成。同時,main執行緒物件才繼續執行,輸出最後的資訊。
擴充套件學習
Java提供join()方法的另外兩種方式:
- join(long milliseconds)
- join(long milliseconds, long nanos)
第一種join()方法代替不確定的等待呼叫執行緒結束時間,這個方法的引數將作為呼叫執行緒等待的毫秒數。例如,thread1物件中包含thread2.join(1000)指令,thread1將延緩執行,直到以下情形中的任何一種情況發生:
- thread2已經執行結束
- 經過了1000毫秒
當其中一種情況是true,join()方法返回。通過檢測執行緒的狀態獲知是否返回join()方法,因為執行緒已經執行結束或者通過規定的時間。
第二種join()方法與第一種相似,不過它接收引數為毫秒和納秒兩個數值。