Java 線程中幾個狀態說明
定義在Thread類中的 State枚舉中,可以直接查看代碼中的注釋
java.lang.Thread
. State . NEW | RUNNABLE | BLOCKED | WAITING | TIMED_WAITING | TERMINATED
狀態 | 解釋 | 說明 |
---|---|---|
NEW | 新建一個線程對象,還沒有調用start()方法 | new一個線程實例,線程還沒有start |
RUNNABLE | Java線程中將就緒(READY)和運行中(RUNNING)兩種狀態統一為 RUNABLE | 等待被調度或正在運行中 |
BLOCKED | 表示線程阻塞於鎖 | 線程阻塞在進入synchronized修飾的方法或代碼塊時的狀態 |
WAITING | 進行該狀態的線程需要等待其他線程做出一些特定動作(通知或中斷) | 讓出CPU,等待被顯示的喚醒,被喚醒后進入BLOCKED狀態,重新獲取鎖 |
TIMED_WAITING | 不同於waiting,它可以在指定的時間后自行返回 | 超時等待,讓出CPU,時間到了自動喚醒,進入BLOCKED狀態,重新獲取鎖 |
TERMINATED | 表示顯示已經執行完畢 |
RUNNABLE
Java中 RUNNABLE 對應操作系統的幾個狀態
-
READY
- 有資格運行,但還沒有被調度
- 調用線程的 start()方法,進入就緒狀態
- 當前線程 sleep() 方法結束,其他線程 join() 結束,等待用戶輸入完畢,某個線程拿到對象鎖,這些線程也將進入就緒狀態
- 當前線程時間片用完了,調用當前線程的 yield()方法,當前線程進入就緒狀態
- 鎖池里的線程拿到對象鎖后,進入就緒狀態
-
RUNNING
線程調度程序選中該線程進行運行
-
操作系統線程阻塞等待 I/O
JVM 並不關心操作系統線程的實際狀態,從 JVM 看來,等待CPU使用權(操作系統狀態為可運行態)與等待 I/O(操作系統處於等待狀態)沒有區別,都是在等待某種資源,所以都歸入RUNNABLE 狀態
BLOCKED
由synchronized鎖導致進入該狀態(WAITING,TIMED_WAITING狀態下喚醒也可能進入該狀態)
(Java中的 BLOCKED狀態與操作系統中的 阻塞狀態不同)
WAITING
各情況下進入該狀態,線程不會占用CPU,線程會讓出鎖,等待被其他線程喚醒,然后會進入 BLOCKED 狀態,重新競爭鎖。
TIMED_WAITING
各個情況下進入該狀態,線程不會占用CPU,時間到了自動喚醒
-
如果是因為sleep進入該狀態,線程不會釋放鎖,等到時間到了自動喚醒進入RUNNABLE狀態
-
其他情況下線程會釋放鎖,等待其他線程喚醒,超時時間到了自動喚醒,然后進入 BLOCKED狀態,重新競爭鎖
TERMINATED
線程 run()方法完成時,或者主線程main()方法結束時,就認為它終止了。
這個線程對象也許是活的,但是已經不是一個單獨執行的線程了,線程一旦終止了就不能復生,在一個終止的線程上調用 start()方法,會拋出 java.lang.IllegalThreadStateException
異常
下面是 Java中線程的狀態,不是操作系統中線程的狀態
Java 中的線程與操作系統中線程的區別
操作系統中進程(線程)的狀態有:
-
初始狀態(NEW)
對應 Java中的
-
可運行狀態(READY)
對應 Java中的 RUNNBALE 狀態
-
運行狀態(RUNNING)
對應 Java中的 RUNNBALE 狀態
-
等待狀態(WAITING)
該狀態在 Java中被划分為了 BLOCKED,WAITING,TIMED_WAITING 三種狀態
當線程調用阻塞式 API時,進程(線程)進入等待狀態,這里指的是操作系統層面的。從 JVM層面來說,Java線程仍然處於 RUNNABLE 狀態。
JVM 並不關心操作系統線程的實際狀態,從 JVM 看來,等待CPU使用權(操作系統狀態為可運行態)與等待 I/O(操作系統處於等待狀態)沒有區別,都是在等待某種資源,所以都歸入RUNNABLE 狀態
-
終止狀態 (TERMINATED)
參考博客