首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

深度解析 Java 執行緒的 6 大狀態與生命週期轉換

     編輯:Java 相關知識

掌握執行緒狀態是編寫高併發程式、排查死鎖/飢餓問題的基礎。Java Thread.State 枚舉定義了 6 種狀態,本文結合源碼與實際場景,詳細解析每種狀態的觸發條件、轉換路徑及常見誤區。

六大狀態速覽表

狀態枚舉常量核心含義典型觸發場景
新建NEW執行緒物件已建立,尚未啟動new Thread()
可執行RUNNABLE在 JVM 中執行中,或等待作業系統排程 CPUthread.start() 後、佔用 CPU 時、等待 CPU 時
阻塞BLOCKED等待監視器鎖(進入 synchronized 區塊/方法)嘗試進入已被佔用的 synchronized 區塊
等待WAITING無限期等待另一執行緒的特定動作Object.wait()、Thread.join()、LockSupport.park()
定時等待TIMED_WAITING帶超時的等待Thread.sleep()、Object.wait(timeout)、Thread.join(timeout)、LockSupport.parkNanos/Until
終止TERMINATED執行緒已結束執行run() 正常返回、拋出未捕獲異常

關鍵狀態轉換圖解

NEW --start()--> RUNNABLE --執行/等待CPU--> RUNNABLE
RUNNABLE --synchronized(鎖被佔用)--> BLOCKED --獲取鎖--> RUNNABLE
RUNNABLE --wait()/join()/park()--> WAITING --notify()/notifyAll()/interrupt()--> RUNNABLE
RUNNABLE --sleep(timeout)/wait(timeout)/join(timeout)/parkNanos/Until--> TIMED_WAITING --超時/通知/中斷--> RUNNABLE
RUNNABLE --run()結束/異常--> TERMINATED

實戰易混淆點釐清

BLOCKED vs WAITING

  • BLOCKED:主動爭搶鎖,進入 synchronized 失敗,鎖釋放自動恢復 不可中斷
  • WAITING:主動釋放鎖並等待通知,需他執行緒喚醒,interrupt() 可打斷並拋出 InterruptedException

為什麼沒有 RUNNING 狀態?

JVM 將「正在執行」與「就緒等待 CPU」合併為 RUNNABLE,因作業系統排程器對 JVM 不透明,JVM 無法區分執行緒當下是佔用 CPU 還是排隊中。

Thread.State 獲取時機

Thread t = new Thread(() -> { /* ... */ });
System.out.println(t.getState()); // NEW
t.start();
System.out.println(t.getState()); // 通常是 RUNNABLE,極罕見 BLOCKED/WAITING

注意:getState() 僅供監控/除錯,不可用於同步控制(狀態讀取到使用之間可能已變更)。

排查實戰:使用 jstack 觀察生產環境執行緒狀態

# 導出執行緒快照
jstack -l <pid> > thread_dump.txt

# 關注重點
# BLOCKED 大量出現 → 鎖爭用嚴重,檢查 synchronized 範圍、考慮 ReentrantLock/分段鎖
# WAITING/TIMED_WAITING 大量 → 線程池空閒、資源池耗盡、外部呼叫慢
# RUNNABLE 但 CPU 低 → 可能在進行 GC、JNI 呼叫、大量系統呼叫

總結

理解 6 大狀態及其轉換,是從「會用多執行緒」進階到「駕馭多執行緒」的必修課。建議配合 jstack、VisualVM、Arthas 等工具,在真實專案中觀察、驗證、內化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved