多線程是 Java 並發編程的基石,亦是面試必考、實戰核心。本系列從線程生命週期、三種建立方式、狀態轉換、啟動與終止機制切入,配合原始碼級分析與實戰範例,建立扎實的多線程心智模型。

| 狀態 | 英文 | 觸發條件 | 說明 |
|---|---|---|---|
| 新建 | NEW | new Thread() | 物件建立,未啟動 |
| 可執行 | RUNNABLE | start() | 就緒佇列等待 CPU 調度(含 Running) |
| 運行 | RUNNING | 獲得 CPU 時間片 | 實際執行 run() 邏輯 |
| 阻塞 | BLOCKED | 見下文三類 | 暫時放棄 CPU,需外部條件喚醒 |
| 死亡 | TERMINATED | run() 結束/異常 | 生命週期結束 |
wait() → 需 notify()/notifyAll() 喚醒synchronized 鎖失敗 → 進入 Entry Set 等待sleep()、join()、I/O 操作 → 時間到/完成自動轉 RUNNABLEclass MyThread extends Thread {
@Override public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + " " + i);
}
}
}
// 使用
Thread t1 = new MyThread();
t1.start(); // 必須呼叫 start(),而非 run()!
關鍵:start() 啟動新線程並呼叫 run();直接呼叫 run() 只在主線程順序執行。
class MyTask implements Runnable {
@Override public void run() { /* 任務邏輯 */ }
}
// 使用
Runnable task = new MyTask();
new Thread(task).start();
new Thread(task).start(); // 同一任務實例可被多線程共享
優勢:任務與線程分離、支援共享實例、避免單一繼承限制、適合線程池提交。
class MyCallable implements Callable<Integer> {
@Override public Integer call() {
int sum = 0;
for (int i = 0; i < 100; i++) sum += i;
return sum; // 有回傳值
}
}
// 使用
FutureTask<Integer> ft = new FutureTask<>(new MyCallable());
new Thread(ft).start();
Integer result = ft.get(); // 阻塞等待結果
System.out.println("Sum = " + result); // 4950
FutureTask 同時實作 Runnable 與 Future,兼具「可被線程執行」與「可獲取結果」雙重特性。
Thread 實作了 Runnable
│
├─ run() { if (target != null) target.run(); } // 委派給 target
│
└─ new Thread(runnable) → target = runnable
若同時繼承 Thread 並傳入 Runnable,子類別覆寫的 run() 會被執行(多態),Runnable 的 run() 被忽略。
| 轉換 | 觸發 |
|---|---|
| RUNNABLE → RUNNING | 獲得 CPU 時間片 |
| RUNNING → RUNNABLE | yield() / 時間片用盡 / 失去 CPU |
| RUNNING → TERMINATED | run() 正常結束 / 未捕獲異常 |
| RUNNING → BLOCKED | sleep()/wait()/join()/I/O/鎖競爭 |
| BLOCKED → RUNNABLE | 喚醒/超時/I/O 完成/獲得鎖 |
Thread.yield(); // 僅「建議」讓出 CPU,調度器可能立即再次選中同一線程
不可依賴 yield() 實現同步邏輯。
class ControlledTask implements Runnable {
private volatile boolean stop = false; // volatile 保證可見性
@Override public void run() {
while (!stop && !Thread.currentThread().isInterrupted()) {
// 執行任務邏輯
}
}
public void requestStop() { stop = true; }
}
// 使用
ControlledTask task = new ControlledTask();
Thread t = new Thread(task);
t.start();
// ... 適當時機
task.requestStop(); // 通知線程退出迴圈
關鍵點:
volatile 確保主線程修改對工作線程可見isInterrupted() 處理 interrupt() 呼叫stop()/suspend()/resume()(破壞鎖一致性)public class ThreadLifecycleDemo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println("狀態: " + Thread.currentThread().getState()); // RUNNABLE
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("睡醒狀態: " + Thread.currentThread().getState()); // RUNNABLE
});
System.out.println("新建: " + t.getState()); // NEW
t.start();
System.out.println("啟動後: " + t.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println("睡眠中: " + t.getState()); // TIMED_WAITING (睡眠)
t.join();
System.out.println("結束: " + t.getState()); // TERMINATED
}
}
start() ≠ run(),yield() 不保證讓出。volatile boolean 標誌位 + interrupt() 雙重保障。