Udemy Course Multithreading, Concurrency & Performance 6

Threads coordination with Thread.join()

ZONGRU Li
Jun 28, 2021

前幾節學到的Thread特性:

  1. 不同Threads間彼此獨立
  2. Threads啟動無法控制(複數Threads背後執行的排程不受控)

假設有兩個Thread間工作彼此相關聯,例如ThreadA將計算結果交給ThreadB

待ThreadA將結果交給ThreadB並結束後,ThreadB才開始運算

我們總不能在兩個Thread job內寫邏輯一直去檢查另一個Thread結束了沒

此時就可以利用join()這個Method

先理解一下BigInteger的multiply(乘以)的運作:

首先建立一個數字陣列,並且嘗試塞入一個正整數

用thread計算出每個數字往下連乘至1

比如23L即計算出23!(即23的乘積)等於2.5852017e+22

接著在底下建立可以計算數字乘積的thread class

首先建立起始值(初始結果為1開始)

寫出計算式factorial(利用BigInteger的相乘multiply)

接著回頭要Main裡面將數字加進thread並計算各自的乘積,並啟動

完整程式如下:

執行後可以看到只有23算完乘積23!,其他數字太大,各自Thread還在算:

那麼希望每一個乘積計算的thread都完成計算,則可以在啟動後加入join()

得到結果

由上可以看到執行完join後,每個thread計算一定已經結束

才進到最後印結果的for迴圈

但是假設我們第一個數字給非常大:

用debug mode跑會看到

切到debug視窗看到main與thread-0(就是那個超大乘積)還在Running

main thread估計是卡在join那個for迴圈的第一個圈等待中

那麼為了避免被使用者亂key不合理數字,導致main無法結束

可以在join裡面給予時間

2000毫秒

但是看到debug視窗,main thread已經跑完了

剩下那個thread-0(超大乘積)還在跑

由前面小節我們知道該如何於main thread結束時,強制其他thread也結束:

再次用debug mode執行可以看到:

程式如下

結論:

  1. 不要依賴thread本身固定排程,因為我們沒辦法掌握
  2. 使用thread coordination也就是本節學到的Thread.join()
  3. 用遭告的案例來測試(如上超大數字乘積)
  4. Thread可能因各種因素跑太久
  5. 承上,記得在Thread.join(..)裡面設置時間限制
  6. 如果有無法在時間內結束的Thread,想辦法中止它

參考課程

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!

No responses yet