1. 程式人生 > 實用技巧 >Java執行緒狀態 與 作業系統執行緒狀態

Java執行緒狀態 與 作業系統執行緒狀態

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 和 RUNNING

  • READY

    • 有資格執行,但還沒有被排程
    • 呼叫執行緒的 start()方法,進入就緒狀態
    • 當前執行緒 sleep() 方法結束,其他執行緒 join() 結束,等待使用者輸入完畢,某個執行緒拿到物件鎖,這些執行緒也將進入就緒狀態
    • 當前執行緒時間片用完了,呼叫當前執行緒的 yield()方法,當前執行緒進入就緒狀態
    • 鎖池裡的執行緒拿到物件鎖後,進入就緒狀態
  • RUNNING

    執行緒排程程式選中該執行緒進行執行

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中被劃分為了 BLOCKEDWAITINGTIMED_WAITING 三種狀態

    當執行緒呼叫阻塞式 API時,程序(執行緒)進入等待狀態,這裡指的是作業系統層面的。從 JVM層面來說,Java執行緒仍然處於 RUNNABLE 狀態

    JVM 並不關心作業系統執行緒的實際狀態,從 JVM 看來,等待CPU使用權(作業系統狀態為可執行態)與等待 I/O(作業系統處於等待狀態)沒有區別,都是在等待某種資源,所以都歸入RUNNABLE 狀態

  • 終止狀態 (TERMINATED)

作業系統執行緒模型

使用者態

當執行緒在使用者態下實現時作業系統是不知道該使用者態執行緒的存在的,僅能看到使用者態的程序,而不能看到執行緒。

程式設計師需要自己實現執行緒的資料結構,建立銷燬和排程維護,也就是相當於需要實現一個自己的執行緒排程核心,而這些執行緒執行在作業系統的一個程序中,最後由作業系統直接對程序進行排程。

graph LR A[CPU] --> |排程程序| B(程序A) A --> |排程程序| C(程序B) B --> E{執行緒1} B --> F{執行緒2} C --> G{執行緒3} C --> H{執行緒4}

核心態

待續


參考部落格

Java執行緒狀態

作業系統執行緒休眠與Java RUNNABLE問題

Java 執行緒與作業系統執行緒