NEW (新建) → start() → RUNNABLE (就緒) ⇄ RUNNING (運行)
↑ ↓
│ BLOCKED (阻塞)
│ (同步鎖/IO/sleep/wait)
└──────────────┘
↓
TERMINATED (終止)
new Thread(),僅分配資源start() 後,等待 CPU 調度 (含就緒+運行)synchronized 鎖wait()、join() (無超時)sleep()、wait(timeout)、join(timeout)、IO 操作run() 正常返回或拋出未捕獲異常| 方式 | 核心代碼 | 優點 | 缺點 |
|---|---|---|---|
| 繼承 Thread | class MyThread extends Thread { run(){} } | 簡單、可直接 this.getName() | 單繼承限制、邏輯與控制耦合 |
| 實現 Runnable | class MyTask implements Runnable { run(){} } new Thread(new MyTask()).start() | 邏輯分離、可共享任務實例、支持線程池 | 需包裝 Thread 獲取線程信息 |
| Callable + FutureTask | new Thread(new FutureTask<>(() -> { return result; })).start() | 有返回值、可拋受檢異常、支持取消/超時 | 語法稍繁瑣 |
// Thread 實現了 Runnable
public class Thread implements Runnable {
private Runnable target;
public Thread(Runnable target) { this.target = target; }
@Override public void run() { if (target != null) target.run(); }
}
// 多態陷阱:若子類重寫 run(),target.run() 不會被調用!
class MyThread extends Thread {
public MyThread(Runnable r) { super(r); }
@Override public void run() { System.out.println("子類 run"); } // 覆蓋父類邏輯
}
new Thread(new MyThread(() -> System.out.println("Lambda"))).start();
// 輸出: "子類 run" ———— Lambda 丟失!
教訓:繼承 Thread 時不要同時傳 Runnable,或調用 super.run()。
Thread.stop() / suspend() / resume():已棄用,導致鎖強制釋放、數據不一致interrupt() 後不檢查狀態:線程繼續執行
class Worker implements Runnable {
private volatile boolean running = true;
public void shutdown() { running = false; }
@Override public void run() {
while (running && !Thread.currentThread().isInterrupted()) {
try {
// 業務邏輯
Thread.sleep(100); // 可響應 interrupt
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 重置標誌
break; // 或拋出
}
}
// 清理資源
}
}
// 使用
Worker w = new Worker();
Thread t = new Thread(w); t.start();
// ... 後續停止
w.shutdown(); t.interrupt(); // 雙重保障
| 方法 | 釋放鎖 | 狀態轉換 | 典型用途 |
|---|---|---|---|
yield() | 否 | RUNNING → RUNNABLE | 禮讓 CPU,同優先級輪轉 |
sleep(ms) | 否 | RUNNING → TIMED_WAITING | 定時任務、限流 |
join() | 否 | RUNNING → WAITING/TIMED_WAITING | 等待另一線程結束 |
wait() | 是 | RUNNING → WAITING | 條件變量協作 (需在 synchronized 中) |
setDaemon(true) 必須在 start() 前調用掌握 Thread 的生命周期狀態機、三種創建模式的本質區別、安全停止模式、核心輔助方法語義,是 Java 併發編程的入門基石。實戰中:優先 Runnable + 線程池、volatile 標誌位停止、避免直接操作 Thread 實例,複雜協作轉用 java.util.concurrent 組件。