Java的多執行緒之等待其他執行緒執行完成,三匹馬的賽事

作者 | 2017-10-19

在設計多執行緒Threading程式時,常需要等待其他執行緒的執行結果,收集資訊後再進一步處理,本文章延續上一篇文章:

Java的多執行緒,以賽馬為例,學習如何繼承Thread與實作Runnable

在上一篇文章中,以main執行緒為第一匹馬,另外以Horse執行緒為第二匹馬,現在想讓main方法專心處理產生執行緒與計算賽馬名次等工作,因此,改變為三匹馬都以Horse執行緒來執行,在main方法中產生三個Horse執行緒物件,利用Thread的方法setName()給予三匹馬執行緒名稱(h1,h2,h3),main方法執行到最後時,印出「main執行緒結束」:

sleep方法

為了方便觀察Horse執行緒的執行結果,將原for迴圈改為讓執行緒睡覺2秒鐘,可使用Thread的方法sleep(long millis),共2000毫秒,sleep方法使用時必須以try…catch處理被意外中斷的例外InterruptedException:

執行Racing3類別的結果如下(每次結果有可能不一樣):

發現一個問題了嗎?就是main執行緒是三匹馬執行緒的發起者,但它卻比三匹馬執行緒還要早結束,若是如此,我們將無法在三匹馬跑出結果時印出到達順序,如何能讓main執行緒等待三匹馬執行緒都結束後,才繼續往後執行呢?

如果讓main執行緒進入睡眠一段時間,雖然可以在睡醒時進行後續的動作,但如果睡覺時間不夠準確,或是三匹馬的執行緒完成時間是未知時,sleep()方法也就不適合用來等待其他「子執行緒」,因此,可以利用join()方法達到等待其他執行緒完成後,再進行後續的動作。

join()方法-等待

Thread類別的方法join(),可以用來等待該執行緒完成,使用join()方法時,和sleep()方法一樣,必須以try…catch處理被意外中斷的例外InterruptedException,如下:

觀察執行結果可發現,main執行緒會等待三匹馬執行緒都完成後,才會繼續第21行的執行:

結算賽馬的名次

瞭解如何利用join()方法來等待子執行緒之後,先訂定一個放置三匹馬的集合rank,第一匹到達的馬可以進入到rank集合的第1個位置,第二匹到達的馬則進入到rank集合的第2的位置,以此類推。使用java.util.ArrayList做為集合類別,新增一類別Racing4來設計此功能:

上述程式碼第7行,新增一個List物件rank,而且以「一般化」限定rank集合裏只能放置RankHorse物件,第8-10行則利用RankHorse的建構子將rank物件傳遞給執行緒類別RankHorse內部使用,最後在第24行依序印出rank集合內的所有物件(三匹馬)。因此,我們還要依照先前Horse類別的模式,再設計RankHorse類別,使其擁有排名的功能,範例程式如下:

上述程式的第4行,定義了成員rank,第6-8行則新增了建構子,以接收Racing4所傳來的rank物件,最後,等到此匹馬到達終點時,第17行將自己放入rank集合中,若此匹馬是第一名到達,將會放置在第一位。

Racing4類別的執行結果如下,可以看到rank集合內依照到達順序的三匹馬:

 

集合內的每匹RankHorse的h1,h2,3是執行緒的名稱,接著逗號後跟著該執行緒的優先權值,預設是5,有關執行優先權之後再另以文章介紹。

版權聲明

本文章授權範圍僅限綠豆湯網站使用,除Facebook之類社群等未更改本文章出處之分享行為不在此限,其他個人或公司未經作者同意,不得任意將本文章內容轉載至其他網站,或以任何形式重製,為以免觸犯著作權法,請尊重作者之智慧財產權。

相關文章:

Category: Java 多執行緒Threading 標籤:, , ,

關於 Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 ,為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *