線程狀態
操作系統層面,線程分為五種狀態
- 創建狀態:線程正在被創建,包括申請資源、分配空間等操作。
- 就緒狀態:已獲得除 CPU 外的一切所需資源。
- 運行狀態:獲得 CPU 正在運行。
- 阻塞狀態:因等待某一事件而暫停運行,如等待 I/O 操作完成。
- 終止狀態:執行完畢,正在進行資源釋放等操作。
Java API 層面,線程分為六種狀態
-
NEW:語言層面創建了線程對象,未與操作系統線程關聯。
Thread state for a thread which has not yet started.
-
RUNNABLE:start()方法被調用,涵蓋操作系統層面的就緒、運行、阻塞狀態。
Thread state for a runnable thread.
A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor. -
BLOCKED:等待Monitor鎖。
Thread state for a thread blocked waiting for a monitor lock.
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling. -
WAITING:等待其他線程執行特定操作使得當前線程滿足繼續執行的條件,此處條件通常是人為設定的。
Thread state for a waiting thread.
A thread is in the waiting state due to calling one of the following methods: Object.wait, Thread.join, LockSupport.park.
A thread in the waiting state is waiting for another thread to perform a particular action. -
TIMED_WAITING:待時限的WAITING狀態。
Thread state for a waiting thread with a specified waiting time.
A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time: Object.wait, Thread.join, LockSupport.parkNanos, LockSupport.parkUntil. -
TERMINATED:執行完畢。
Thread state for a terminated thread.
The thread has completed execution.
無特別説明,以下所涉及的線程狀態均指 Java API 層面的狀態。
NEW ==> RUNNABLE
當調用 t.start() 方法時,線程 t 的狀態由 NEW 轉為 RUNNABLE。
RUNNABLE <==> WAITING
wait & notify
線程 t 執行 synchronized(obj) 後,調用 obj.wait() 方法
- 線程 t 由 RUNNABLE 轉為 WAITING
-
其他線程調用 obj.notify()、obj.notifyAll()、t.interrupt()
- 線程 t 若競爭鎖成功,則由 WAITING 轉為 RUNNABLE。
- 線程 t 若競爭鎖失敗,則由 WAITING 轉為 BLOCKED。
join
當前線程調用 t.join() 方法
- 當前線程從 RUNNABLE 轉為 WAITING。
- 線程 t 執行完畢或當前線程的 interrupt() 方法被調用,當前線程從 WAITING 轉為 RUNNABLE。
park & unpark
線程 t 調用 LockSupport.park() 方法
- 線程 t 從 RUNNABLE 轉為 WAITING。
- 調用 LockSupport.unpark(t) ,或調用 t.interrupt() 方法,線程 t 從 WAITING 轉為 RUNNABLE。
RUNNABLE <==> TIMED_WAITING
和 RUNNABLE 與 WAITING之間的轉換類似,TIMED_WAITING 是帶時限的 WAITING。
線程 t 執行 synchronized(obj) 後,調用 obj.wait(long) 方法
- 線程 t 由 RUNNABLE 轉為 WAITING
-
線程 t 等待超時,或其他線程調用 obj.notify()、obj.notifyAll()、t.interrupt()
- 線程 t 若競爭鎖成功,則由 WAITING 轉為 RUNNABLE。
- 線程 t 若競爭鎖失敗,則由 WAITING 轉為 BLOCKED。
join
當前線程調用 t.join(long) 方法
- 當前線程從 RUNNABLE 轉為 WAITING。
- 線程 t 執行完畢,或當前線程等待超時,或當前線程的 interrupt() 方法被調用,當前線程從 WAITING 轉為 RUNNABLE。
park & unpark
線程 t 調用 LockSupport.parkNanos(long) 或 LockSupport.parkUntil(long) 方法
- 線程 t 從 RUNNABLE 轉為 WAITING。
- 調用 LockSupport.unpark(t) ,或線程 t 等待超時,或調用 t.interrupt() 方法,線程 t 從 WAITING 轉為 RUNNABLE。
sleep
線程 t 調用 Thread.sleep(long)
- 線程 t 從 WAITING 轉為 RUNNABLE。
- 線程 t 等待超時,或調用 t.interrupt() 方法,線程 t 從 WAITING 轉為 RUNNABLE。
RUNNABLE <==> BLOCKED
- 線程 t 競爭鎖失敗,從 RUNNABLE 轉為 BLOCKED。
- 線程 t 競爭鎖成功,從 BLOCKED 轉為 RUNNABLE。
RUNNABLE ==> TERMINATED
線程 t 執行完畢,從 RUNNABLE 轉為 TERMINATED。
狀態辨析
BLOCKED 和 WAITING/TIMED_WAITING
- 存放:BLOCKED 狀態的線程存放在 Monitor 對象的 EntryList 中,WAITING 狀態的線程存放在 Monitor 對象的 WaitSet 中。
- 等待:BLOCKED 狀態的線程在等待鎖,WAITING 狀態的線程在等待人為設置的條件成立,或者説在等待其他線程將其喚醒。
- 調度:BLOCKED 可被 CPU 調用,WAITING 狀態的線程只有被其他線程喚醒後才能被 CPU 調度。
操作系統的 BLOCKED 和 Java API 的 BLOCKED
- 操作系統的 BLOCKED,指線程正在等待某種資源(如打印機)或者等待某個操作完成(如 I/O)。
- Java API 的 BLOCKED,指線程正在等待鎖。
END
文章文檔:公眾號 字節幺零二四 回覆關鍵字可獲取本文文檔。