java執行緒狀態轉化
阿新 • • 發佈:2019-01-24
先來一張執行緒狀態轉化圖,然後我再慢慢解釋:
在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
有資源有執行權:執行態
有資源無執行權:就緒態
無資源無執行權:阻塞態(會一直請求資源)
主動釋放資源和執行權,不設定超時時間,需要被喚醒:等待態
主動釋放資源和執行權,設定超時時間,能自動喚醒:超時等待態