執行緒停止繼續 如何優雅的停止乙個執行緒?

2021-10-25 13:22:21 字數 2525 閱讀 2863

在之前的文章中 i-code.online -《併發程式設計-執行緒基礎》我們介紹了執行緒的建立和終止,從原始碼的角度去理解了其中的細節,那麼現在如果面試有人問你 「如何優雅的停止乙個執行緒?」, 你該如何去回答尼 ?能不能完美的回答尼?

這裡有個思考: 當處於sleep時,執行緒能否感受到中斷訊號?

對於執行緒的停止,最優雅的方式就是通過interrupt的方式來實現,關於他的詳細文章看之前文章即可,如interruptedexception時,再次中斷設定,讓程式能後續繼續進行終止操作。不過對於interrupt實現執行緒的終止在實際開發中發現使用的並不是很多,很多都可能喜歡另一種方式,通過標記位。

/** * @url: i-code.online * @author: zhoucx * @time: 2020/10/12 10:46 */public class producter implements runnable     @override    public void run()                 num++;            }        } catch (interruptedexception e) finally     }}
首先,宣告了乙個生產者producer,通過volatile標記的初始值為true的布林值mark來停止執行緒。而在run()方法中,while的判斷語句是num是否小於100000mark是否被標記。while迴圈體中判斷num如果是 50 的倍數就放到numqueue倉庫中,numqueue是生產者與消費者之間進行通訊的儲存器,當num大於100000或被通知停止時,會跳出while迴圈並執行finally語句塊,告訴大家「生產者執行結束」

/** * @url: i-code.online * @author: zhoucx * @time: 2020/10/12 11:03 */public class consumer implements runnable    @override    public void run()         } catch (interruptedexception e)  finally     }}
而對於消費者consumer,它與生產者共用同乙個倉庫numqueue,在run()方法中我們通過判斷隨機數大小來確定是否要繼續消費,剛才生產者生產了一些 50 的倍數供消費者使用,消費者是否繼續使用數字的判斷條件是產生乙個隨機數並與 0.97 進行比較,大於 0.97 就不再繼續使用數字。

/** * @url: i-code.online * @author: zhoucx * @time: 2020/10/12 11:08 */public class mian }
主函式中很簡單,建立乙個 公共倉庫queue長度為10,然後傳遞給兩個執行緒,然後啟動兩個執行緒,當我們啟動後要注意,我們的消費時有睡眠100毫秒,那麼這個公共倉庫必然會被生產者裝滿進入阻塞,等待消費。

當消費者不再需要資料,就會將 canceled 的標記位設定為 true,理論上此時生產者會跳出 while 迴圈,並列印輸出「生產者執行結束」。

然而結果卻不是我們想象的那樣,儘管已經把producter.mark設定成false,但生產者仍然沒有停止,這是因為在這種情況下,生產者在執行numqueue.put(num)時發生阻塞,在它被叫醒之前是沒有辦法進入下一次迴圈判斷producter.mark的值的,所以在這種情況下用volatile是沒有辦法讓生產者停下來的,相反如果用interrupt語句來中斷,即使生產者處於阻塞狀態,仍然能夠感受到中斷訊號,並做響應處理。

通過上面的介紹我們知道了,執行緒終止的主要兩種方式,一種是 `interrupt` 一種是`volatile` ,兩種類似的地方都是通過標記來實現的,不過`interrupt` 是中斷訊號傳遞,基於系統層次的,不受阻塞影響,而對於 `volatile` ,我們是利用其可見性而頂乙個標記位標量,但是當出現阻塞等時無法進行及時的通知。

在我們平時的開發中,我們視情況而定,並不是說必須使用 `interrupt` ,在一般情況下都是可以使用 `volatile` 的,但是這需要我們精確的掌握其中的場景。

如何優雅的停止乙個執行緒

首先我們先了解下,執行緒是分為使用者執行緒和守護執行緒的,他們的區別就在 使用者執行緒當我們的主線程停止後,使用者執行緒不會隨著主線程停止。守護執行緒當我們的主線程停止後,會跟隨著主線程一起停止。一般我們建立的都是使用者執行緒,那守護執行緒有哪些呢,例如跟程式一起啟動的gc執行緒就是守護執行緒。停止...

如何停止乙個執行緒

停止乙個執行緒的最佳方法是讓它執行完畢,沒有辦法立即停止乙個執行緒,但你可以控制何時或什麼條件下讓他執行完畢。通過條件變數控制線程的執行,執行緒內部檢查變數狀態,外部改變變數值可控制停止執行。為保證執行緒間的即時通訊,需要使用volatile關鍵字或鎖,確保讀執行緒與寫執行緒變數狀態的一致性。pub...

優雅的停止執行緒

thread類的start 方法啟動多執行緒,thread原本也有提供有停止方法stop 但從1.2開始已經廢除了,因為這種方法可能造成執行緒的死鎖,現在實現執行緒的停止需要通過一種柔和的方式進行。範例 實現執行緒柔和的停止 package multithreading public class s...