執行緒管理(六)等待執行緒的終結
宣告:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 譯者:鄭玉婷 校對:方騰飛
等待執行緒的終結
在某些情況下,我們需要等待執行緒的終結。例如,我們可能會遇到程式在執行前需要初始化資源。在執行剩下的程式碼之前,我們需要等待執行緒完成初始化任務。
為達此目的, 我們使用Thread 類的join() 方法。當前執行緒呼叫某個執行緒的這個方法時,它會暫停當前執行緒,直到被呼叫執行緒執行完成。
在這個指南中, 我們將學習用初始化例子來使用這個方法。
準備
指南中的例子是使用Eclipse IDE 來實現的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 開啟並建立一個新的java專案。
怎麼做呢…
按照這些步驟來實現下面的例子::
1. 建立一個類名為 DataSourcesLoader 並一定實現Runnable介面。
public class DataSourcesLoader implements Runnable {
2. 實現run()方法。 它寫資訊來表明它開始執行,然後睡眠4秒,最後再寫資訊表明它結束執行。
@Override public void run() { System.out.printf("Beginning data sources loading: %s\n",new Date()); try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Data sources loading has finished:%s\n",new Date()); }
3. 建立一個類名為 NetworkConnectionsLoader 並一定要Runnable介面。實現run()方法。它將與DataSourcesLoader類的run()方法一樣,但是它會睡眠6秒。
4. 現在, 建立一個類名為 Main,包含 main()方法。
public class Main { public static void main(String[] args) {
5. 建立一個 DataSourcesLoader 類物件並讓執行緒執行它。
DataSourcesLoader dsLoader = new DataSourcesLoader(); Thread thread1 = new Thread(dsLoader,"DataSourceThread");
6. 建立一個 NetworkConnectionsLoader 類的物件並讓執行緒執行它。
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader(); Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoad er");
7. 讓2個執行緒物件都呼叫 start() 方法。
thread1.start(); thread2.start();
8. 2個執行緒都使用 join() 方法等待終結。 此方法可以丟擲InterruptedException 異常, 所以要包含捕捉程式碼。
try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
9. 寫一條資訊表明程式結束。
System.out.printf("Main: Configuration has been loaded: %s\n",new Date());
10. 執行程式並檢視結果。
它是怎麼工作的…
當你執行這個程式時,你可以發現2個執行緒物件都開始他們的執行。首先, DataSourcesLoader 結束它的執行。然後, NetworkConnectionsLoader 類結束它的執行,同時,主執行緒物件繼續執行並寫下了最後的資訊。
更多
Java 提供2種形式的 join() 方法:
- join (long milliseconds)
- join (long milliseconds, long nanos)
第一種join() 方法, 這方法讓呼叫執行緒等待特定的毫秒數。例如,如果thread1物件使用程式碼thread2.join(1000), 那麼執行緒 thread1暫停執行,直到以下其中一個條件發生:
- thread2 結束執行
- 1000 毫秒過去了
當其中一個條件為真時,join() 方法返回。
第二個版本的 join() 方法和第一個很像,只不過它接收一個毫秒數和一個納秒數作為引數。