博客 / 詳情

返回

併發編程:Java線程狀態及其轉換

線程狀態

操作系統層面,線程分為五種狀態

  • 創建狀態:線程正在被創建,包括申請資源、分配空間等操作。
  • 就緒狀態:已獲得除 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

文章文檔:公眾號 字節幺零二四 回覆關鍵字可獲取本文文檔。

user avatar prepared 頭像 mo_or 頭像 buxiyan 頭像 longbig 頭像 lianhuatongzina 頭像
5 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.