Java 執行緒從建立到終止,會經歷 新建、就緒、執行、阻塞、死亡 五種狀態。理解狀態轉換觸發條件與 JVM 排程機制,是撰寫高併發程式、排查死鎖與效能瓶頸的基礎。本文結合狀態圖解與完整程式碼示範,深入剖析各狀態轉換細節。
| 狀態 | 英文 | 觸發條件 / 說明 |
|---|---|---|
| 新建 | NEW | new Thread() 建立物件,尚未呼叫 start() |
| 就緒 | RUNNABLE | 呼叫 start() 後,進入排程佇列等待 CPU 分派 |
| 執行 | RUNNING | 獲得 CPU 時間片,正在執行 run() 方法 |
| 阻塞 | BLOCKED | 呼叫 sleep()、wait()、join()、I/O 操作、等待鎖(synchronized) |
| 死亡 | TERMINATED | run() 正常結束、拋出未捕獲異常、呼叫 stop()(已棄用) |
Thread.sleep(ms) 放棄 CPU,時間到自動轉就緒obj.wait() 釋放鎖進入等待集,需 notify()/notifyAll() 喚醒synchronized 區塊但鎖被佔用thread.join() 等待目標執行緒終止注意:阻塞狀態無法直接轉執行,必須先轉就緒,再由排程器分派 CPU。
MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10setPriority(int) 調整,但僅是提示,不保證執行順序public class UserThread extends Thread {
public UserThread(String name) { super(name); }
@Override public void run() {
System.out.println(getName() + " started running..");
}
public static void main(String[] args) {
UserThread t1 = new UserThread("Thread-1");
UserThread t2 = new UserThread("Thread-2");
System.out.println("初始優先權: " + t1.getPriority()); // 5
t1.setPriority(6);
t2.setPriority(9);
System.out.println("調整後: t1=" + t1.getPriority() + ", t2=" + t2.getPriority());
t1.start(); t2.start();
for (int i = 0; i < 5; i++) System.out.println("main: " + i);
}
}
初始優先權: 5
調整後: t1=6, t2=9
main: 0
main: 1
Thread-1 started running..
main: 2
Thread-2 started running..
main: 3
main: 4
主執行緒與子執行緒交替執行,驗證分時輪詢排程。
run() 直接呼叫 → 不會啟動新執行緒,仍在主執行緒循序執行。必須呼叫 start()CountDownLatch、CyclicBarrier、CompletableFuture 等同步工具setName(),便於日誌追蹤與除錯stop()、suspend()、resume(),改用 interrupt() 與標誌位協作終止掌握執行緒五大狀態轉換圖、阻塞細分與排程特性,能幫助開發者設計更健壯的併發程式。實務上建議善用 java.util.concurrent 高階工具,減少直接操作底層執行緒 API 的複雜度與風險。