線程是 Java 併發編程的基本單位。理解其生命周期對編寫正確、高效的多線程程序至關重要。本文系統梳理線程從誕生到消亡的完整過程,涵蓋創建、運行、阻塞、等待、終止等關鍵狀態轉換。
new Thread() 或繼承 Thread 創建Thread 對象(JVM 堆上)≠ 操作系統線程(OS 調度實體)start() 前:僅有 Thread 對象,無 OS 線程start() 後:OS 創建線程,調用 run()run() 結束:OS 線程銷毀,Thread 對象仍存活(可查詢狀態)最佳實踐:絕不在構造器中調用 start()。構造器未完成時 this 逃逸,新線程可能訪問半初始化對象。應提供單獨的start()/init()方法。
run() 方法執行完畢返回Exception 或 Errorstop()、suspend()、resume() — 嚴禁使用,會破壞鎖一致性導致數據損壞JVM 退出條件:所有非守護線程結束。守護線程(如 GC)不阻止 JVM 退出。
NEW (新建) → start() → RUNNABLE (可運行) ↔ RUNNING (運行中)
↑ ↓
│ sleep/yield/wait │
│ blocked on I/O │
│ synchronized │
└──────── TERMINATED (終止) ←────────┘
Thread t = new Thread(task);
t.start();
// 做其他事...
t.join(); // 阻塞當前線程,直到 t 終止
// t.join(5000) 超時版本
典型場景:主線程分解大任務 → 啟動多工作線程 → 循環 join() 等待所有完成 → 聚合結果。
Thread.sleep(1000); // 休眠 1 秒,不釋放鎖
Thread.sleep(0, 500000); // 納秒精度
interrupt() 喚醒 → 拋出 InterruptedExceptionthread.setDaemon(true); // 必須在 start() 前調用
public class TenThreads {
static class WorkerThread extends Thread {
int max = Integer.MIN_VALUE;
final int[] data;
WorkerThread(int[] data) { this.data = data; }
public void run() {
for (int v : data) max = Math.max(max, v);
}
public int getMax() { return max; }
}
public static void main(String[] args) {
WorkerThread[] threads = new WorkerThread[10];
int[][] matrix = getBigMatrix();
int globalMax = Integer.MIN_VALUE;
for (int i = 0; i < 10; i++) {
threads[i] = new WorkerThread(matrix[i]);
threads[i].start();
}
try {
for (WorkerThread t : threads) {
t.join(); // 等待每個線程完成
globalMax = Math.max(globalMax, t.getMax());
}
} catch (InterruptedException e) { /* 處理中斷 */ }
System.out.println("Maximum value: " + globalMax);
}
}
多線程交替執行順序不可預測。示例:
// 兩線程各打印兩行
Thread1: A → B
Thread2: 1 → 2
// 可能輸出 6 種順序之一,永不假設固定順序!
鐵律:共享可變數據必須同步(synchronized/Lock/volatile/原子類)。
| 階段 | 觸發條件 | 關鍵方法 | 注意事項 |
|---|---|---|---|
| NEW | new Thread() | 構造器 | 未關聯 OS 線程 |
| RUNNABLE | start() | start() | 就緒態,等待 CPU 調度 |
| RUNNING | 獲得 CPU | run() 執行 | 真正執行狀態 |
| BLOCKED | 等待鎖 | synchronized | 不佔用 CPU |
| WAITING | 無限等待 | wait()/join() | 需 notify/終止喚醒 |
| TIMED_WAITING | 限時等待 | sleep/wait/join(timeout) | 超時自動喚醒 |
| TERMINATED | run 結束/異常 | — | 線程死亡,不可重啟 |