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 阻塞。當然了還有很多種情況,如網絡阻塞等等。

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