Java並發編程:線程的基本狀態


一、線程的基本狀態

線程基本上有5種狀態,分別是:NEW、Runnable、Running、Blocked、Dead。

1)新建狀態(New)

當線程對象對創建后,即進入了新建狀態,如:Thread t = new MyThread();

2)就緒狀態(Runnable)

當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處於就緒狀態的線程,只是說明此線程已經做好了准備,隨時等待CPU調度執行,並不是說執行了t.start()此線程立即就會執行;

3)運行狀態(Running)

當CPU開始調度處於就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。注:就     緒狀態是進入到運行狀態的唯一入口,也就是說,線程要想進入運行狀態執行,首先必須處於就緒狀態中;

4)阻塞狀態(Blocked)

處於運行狀態中的線程由於某種原因,暫時放棄對CPU的使用權,停止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根據阻塞產生的原因不同,阻塞狀態又可以分為三種:

1、等待阻塞

運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;

2、同步阻塞

線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態;

3、其他阻塞

通過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。

5)死亡狀態(Dead)

線程執行完了或者因異常退出了run()方法,該線程結束生命周期。

用一張圖來將其概括的話會更容易記憶:

二、線程的生命周期

而一個線程的聲明周期一般從新建狀態(New)開始,到死亡狀態(Dead)結束,中間可以存在許多中可能。

如上圖所示,一般情況下會有4個分支情況。

1)正常情況

如上圖中紅色箭頭所示,正常狀態下線程的聲明周期是這樣的:NEW -> RUNNABLE -> RUNNING -> DEAD。

分別是正常情況(紅色箭頭),發生鎖阻塞(同步阻塞)的情況(藍色箭頭),發生等待阻塞的情況(黃色箭頭),發生其他阻塞的情況(黑色箭頭),分別對應上圖4個不同顏色的流向。

2)發生鎖阻塞(同步阻塞)

如上圖中藍色箭頭所示,當線程進入 RUNNING 狀態時進入了 synchronized 方法塊,這時就會發生鎖阻塞,線程進入一個 Lock Pool 鎖池中。當其獲得鎖之后,又進入到可運行狀態。當CPU分片輪詢到它的時候,它就再次運行,直至 DEAD 狀態。

3)發生等待阻塞

如上圖中藍色箭頭所示,當線程進入 RUNNING 狀態時遇到了 wait() 方法,這時就會發生等待阻塞,它會等待其他線程調用 notify() 方法釋放鎖之后才可恢復到可運行狀態。當CPU分片輪詢到它的時候,它就再次運行,直至 DEAD 狀態。等待阻塞和鎖阻塞其實是同一類型的,都是因為爭奪鎖而發生的線程等待,唯一的不同是因為它們調用的是不同的方式實現,但底層原理相同。要注意的是執行 wait() 方法的時候,線程一定要獲得鎖,所以 wait() 方法一般都在 synchronized 方法或代碼塊中。當其獲得鎖之后進入等待池(wait pool)並釋放鎖。收到 notify() 通知之后等待獲取鎖,獲取鎖之后才可以運行。

4)發生其他阻塞(如:IO讀取等)

當線程需要去讀取文件,而此時文件又被其他線程占用,那么就會發生阻塞。這時候線程需要等待其他線程讀取完之后才能繼續進行,這可以稱為 IO 阻塞。當然了還有很多種情況,如網絡阻塞等等。

 

參考文章:

http://www.cnblogs.com/lwbqqyumidi/p/3804883.html 

http://www.cnblogs.com/mengdd/archive/2013/02/20/2917966.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM