併發基礎(四) java中線程的狀態

一、線程的五種狀態

  線程的生命週期可以大致分爲5種,但這種說法是比較舊的一種說法,有點過時了,或者更確切的來說,這是操作系統的說法,而不是java的說法。但對下面所說的六種狀態的理解有所幫助,所以也寫出來,作爲參考。
1. NEW: 線程的新建狀態,是指通過New關鍵字創建了Thread類(或其子類)的對象。
2. RUNNABLE: 這種情況指的是Thread類的對象調用了start()方法,這時的線程就等待時間片輪轉到自己這,以便獲得CPU;第二種情況是線程在處於RUNNABLE狀態時並沒有運行完自己的run方法,時間片用完之後回到RUNNABLE狀態;還有種情況就是處於BLOCKED狀態的線程結束了當前的BLOCKED狀態之後重新回到RUNNABLE狀態。
3. RUNNING: 這時的線程指的是獲得CPU的RUNNABLE線程,RUNNING狀態是所有線程都希望獲得的狀態。
4. DEAD: 處於RUNNING狀態的線程,在執行完run方法之後,或者異常退出時,就變成了DEAD狀態了。
5. BLOCKED: 這種狀態指的是處於RUNNING狀態的線程,出於某種原因,比如調用了sleep方法、等待用戶輸入等而讓出當前的CPU給其他的線程。
注意: BLOCKED狀態,包括三種類型狀態:等待(wait)、睡眠(sleep)、阻塞(申請資源:I\O、對象的鎖);

二、線程的六種狀態

  在java中,線程的狀態其實是六種,對應着枚舉類型 Thread.State 的六個枚舉常量:NEW 、BLOCKED、RUNNABLE、WAITING 、TIMED_WAITING、TERMINATED

1. NEW : 新建狀態,至今尚未啓動的線程的狀態。
2. BLOCKED: 阻塞狀態,受阻塞並且正在等待監視器鎖的某一線程的線程狀態。
3. RUNNABLE: 可運行線程的線程狀態。這裏其實合併了兩種狀態(RUNNING、RUNABLE)
4. WAITING : 等待狀態,表示線程進入狀態。進入此狀態後,會無限等待,直到其他線程做出一些特定的動作(喚醒通知、中斷通知)纔會再次運行。
5. TIMED_WAITING : 計時等待狀態,此狀態與 WAITING 狀態有些類似,但它是有時間限制的,即只會等待一段指定的時間,當時間到來前,沒有被喚醒或或中斷,那麼時間到來了,就自動”醒來”,進入RUNNABLE狀態。
6. TERMINATED : 終止狀態,已終止線程的線程狀態。

線程在自身的生命週期中,並不是固定地處於某個狀態,而是隨着代碼的執行在不同的狀態之間進行切換,java線程狀態變遷如下圖所示:
這裏寫圖片描述

注意以下幾點:
1、當線程的run方法結束時,該線程就完成。即線程死亡。但注意,此時線程的狀態是死亡了,而且是不可以復活的,但是死亡的線程的對象並沒有立即消失(因爲Thread是一個類,是一個記錄、操作線程的類),特別是在別處被引用下,你可以繼續調用這個Thread實例上的大部分方法,而對線程操作的方法基本上都會拋異常,如:start()、wait()、notify()不可以再調用;
2、只要線程啓動了,也就是調用start()方法,也就永遠就不能再次啓動;
3、線程執行的順序與線程啓動的順序無關,start()線程啓動,線程首先由新建狀態變成就緒狀態,並不是直接就是運行狀態,即不會馬上就運行,何時進入CPU運行,得看調度算法;
4、java 將操作系統當中的就緒 與 運行兩個狀態合併爲運行狀態。
5、線程進入synchronize修飾的方法或代碼塊中,線程的狀態變爲阻塞狀態。但如果線程進入的是Lock接口的代碼塊中,卻是等待狀態。這是因爲Lock對於阻塞的本質實現是使用了LockSupport類中的相關方法。
6、WAITING 、TIMED_WAITING 兩種等待狀態都是可以被”中斷”打斷的,所以那些將線程變爲等待狀態的方法,如wait()、sleep等都要 捕獲 InterruptedException異常。

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