Java---線程的生命週期

    當線程被創建並啓動以後,它既不是已啓動就進入執行狀態,也不是一直處於執行狀態,在線程的生命週期中,它要經過新建(New)就緒(Runnable)運行(Running)阻塞(Blocked)死亡(Dead)5中狀態。尤其是當線程啓動以後,它不可能一直“霸佔”着CPU獨自運行(如果在一個cpu分片時間之內執行完,那就不會切換),所以CPU需要在多條線程之間切換(可以查看cpu多線程實現原理),於是線程狀態也會多次在運行、就緒之間切換。

    1.新建和就緒狀態

    當程序使用new關鍵字創建了一個線程之後,該線程就處於新建狀態,此時它和其他的java對象一樣,僅僅由java虛擬機爲其分配內存,並初始化成員變量的值。此時的線程對象沒有表現出任何線程的動態特徵,程序也不會執行線程的線程執行體。

    當線程對象調用了start()方法後,該線程處於就緒狀態,java虛擬機會爲其創建方法調用棧程序計數器,處於這個狀態中的線程並沒有開始運行,只是表示該線程可以運行了。

    2.運行和阻塞狀態

    如果處於就緒狀態的線程獲得了CPU,開始執行run()方法的線程執行體,則該線程處於運行狀態。如果計算機只要一個CPU,那麼在任何時刻只有一個線程處於運行狀態。在一個多處理器的機器上,將會有多個線程並行(是並行,不是併發:parallel)執行;當線程數大於處理器數時,依然會存在多個線程在同一CPU上輪換的現象(線程調度的策略取決於底層操作系統,目前所有現代的桌面和服務器操作系統都採用搶佔式策略)。

    對於採用搶佔式策略的系統,系統會給每個可執行的線程一小個時間段來處理任務,當該時間段用完後,如果線程還沒有執行完,系統就會剝奪該線程所佔用的資源,讓其他線程獲得執行的機會。在選着下一個線程時,系統會考慮線程的優先級

    當發生如下情況下時,線程將會進入阻塞狀態

        1.線程調用sleep()方法,主動放棄所佔用的處理器資源

        2.線程調用了一個阻塞式IO方法,在該方法返回之前,該線程被阻塞。

        3.線程視圖獲取一個同步監視器,但該同步監視器正被其他線程所持有。

        4.線程等待某個通知(notify)。

        5.程序調用了線程的suspend()方法將該線程掛起。這個方法容易導致死鎖,所以應該儘量避免使用。

    當前正在執行的線程被阻塞之後,其他線程就可以獲得執行的機會。被阻塞的線程會在合適的時候重新進入就緒狀態(是就緒狀態,不是運行狀態)。也就是說,被阻塞線程的阻塞解除後,必須重新等待線程調度器的再次調用。

    線程狀態轉換圖如下所示:

    線程從阻塞狀態只能進入就緒狀態,無法直接進入運行狀態。而就緒和運行狀態之間的轉換通常不受程序控制,而是由操作系統調度所決定。當處於就緒狀態的線程獲得處理器資源時,該線程進入運行狀態,當處於運行狀態的線程失去處理器資源時,該線程進入就緒狀態。但有一個方法例外,調用yield()方法可以讓處於運行狀態的線程轉入就緒(yield()方法將在後面介紹)。

    3.線程死亡

    線程會以如下三種方式結束,結束後就處於死亡狀態

        1.run()或call()方法執行完成,線程正常結束

        2.線程拋出一個未被捕獲的Exception或Error。

        3.直接調用該線程的stop()方法來結束線程---該方法容易導致死鎖,通常不建議使用。

    注:當主線程結束時,其他線程不受任何影響,並不會隨之結束。一旦子線程啓動起來後,它就擁有和主線程相同的地位,它不             受主線程的影響。 

 

     參考來源:《java瘋狂講義》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章