1. 程式人生 > >java執行緒狀態轉化

java執行緒狀態轉化

先來一張執行緒狀態轉化圖,然後我再慢慢解釋:

在Java中執行緒的狀態一共被分成6種:

初始態:NEW

建立一個Thread物件,但還未呼叫start()啟動執行緒時,執行緒處於初始態。

執行態:RUNNABLE

在Java中,執行態包括就緒態 和 執行態。

  • 就緒態
    • 該狀態下的執行緒已經獲得執行所需的所有資源,只要CPU分配執行權就能執行。
    • 所有就緒態的執行緒存放在就緒佇列中。
  • 執行態
    • 獲得CPU執行權,正在執行的執行緒。
    • 由於一個CPU同一時刻只能執行一條執行緒,因此每個CPU每個時刻只有一條執行態的執行緒。

阻塞態

  • 當一條正在執行的執行緒請求某一資源失敗時,就會進入阻塞態。
  • 而在Java中,阻塞態專指請求鎖失敗時進入的狀態。
  • 由一個阻塞佇列存放所有阻塞態的執行緒。
  • 處於阻塞態的執行緒會不斷請求資源,一旦請求成功,就會進入就緒佇列,等待執行。

PS:鎖、IO、Socket等都資源。

等待態

  • 當前執行緒中呼叫wait、join、park函式時,當前執行緒就會進入等待態。
  • 也有一個等待佇列存放所有等待態的執行緒。
  • 執行緒處於等待態表示它需要等待其他執行緒的喚醒才能繼續執行。
  • 進入等待態的執行緒會釋放CPU執行權,並釋放資源(如:鎖)

超時等待態

  • 當執行中的執行緒呼叫sleep(time)、wait、join、parkNanos、parkUntil時,就會進入該狀態;
  • 它和等待態一樣,並不是因為請求不到資源,而是主動進入,並且進入後能夠自動喚醒,不需要其他執行緒喚醒;
  • 進入該狀態後釋放CPU執行權 和 佔有的資源。
  • 與等待態的區別:到了超時時間後自動進入阻塞佇列,開始競爭鎖。

終止態

執行緒執行結束後的狀態。

注意:

  • wait()方法會釋放CPU執行權 和 佔有的鎖。
  • sleep(long)方法僅釋放CPU使用權,鎖仍然佔用;執行緒被放入超時等待佇列,與yield相比,它會使執行緒較長時間得不到執行。
  • yield()方法僅釋放CPU執行權,鎖仍然佔用,執行緒會被放入就緒佇列,會在短時間內再次執行。
  • wait和notify必須配套使用,即必須使用同一把鎖呼叫;
  • wait和notify必須放在一個同步塊中
  • 呼叫wait和notify的物件必須是他們所處同步塊的鎖物件。(不然報錯IllegalMonitorStateException)

轉自:https://www.zhihu.com/question/27654579/answer/252912242 

有資源有執行權:執行態
有資源無執行權:就緒態
無資源無執行權:阻塞態(會一直請求資源)
主動釋放資源和執行權,不設定超時時間,需要被喚醒:等待態
主動釋放資源和執行權,設定超時時間,能自動喚醒:超時等待態