包括線程狀態、Thread.yield()、Thread.join()、線程安全停止、標志位、中斷等,都是線程這塊秋招的重點。
1. 線程狀態(Thread.State)
Java 中線程有 6 種狀態:
狀態 | 含義 | 進入條件 |
---|---|---|
NEW | 新建狀態 | Thread t = new Thread(...); |
RUNNABLE | 可運行狀態 | 調用 start() 后,等待 CPU 調度 |
BLOCKED | 阻塞狀態 | 等待鎖(synchronized) |
WAITING | 無時間限制等待 | Object.wait()、Thread.join()(無超時)、LockSupport.park() |
TIMED_WAITING | 有時間限制的等待 | sleep(millis)、join(millis)、wait(millis) |
TERMINATED | 終止狀態 | 線程執行完 run() 方法 |
注意:
RUNNABLE 不一定在 CPU 上運行,只是處于可運行隊列中。
BLOCKED、WAITING、TIMED_WAITING 是阻塞線程狀態。
2. Thread.yield()
作用:提示線程調度器,當前線程愿意讓出 CPU,但只是“禮貌性提示”,不保證立即切換。
效果:線程從 RUNNING → RUNNABLE,允許同優先級線程運行。
特點:
不阻塞線程
不釋放鎖
示例:
for (int i = 0; i < 10; i++) {System.out.println(i);Thread.yield(); // 提示調度器切換線程
}
3. Thread.join()
作用:讓當前線程等待調用 join() 的線程執行完成。
效果:當前線程進入 WAITING 或 TIMED_WAITING,直到被等待的線程 TERMINATED。
可選超時:join(long millis),超時后線程繼續執行。
示例:
Thread a = new Thread(() -> System.out.println("線程A執行"));
a.start();
a.join(); // 當前線程等待a執行完
System.out.println("主線程繼續");
4. 安全停止線程
4.1 原則
Java 不推薦使用 stop()、suspend()、resume(),會破壞資源和鎖,容易死鎖。
推薦方式:使用標志位(flag)或 interrupt() 請求中斷。
4.2 標志位(Flag)
概念:線程內部定義的布爾變量,用于表示線程是否繼續運行。
特點:
線程自己檢查標志位決定是否退出
使用 volatile 修飾保證線程可見性
這里使用volatile是因為,volatile可以使當前變量的變化能立即被別的線程看到。
示例:
class DownloadTask implements Runnable {private volatile boolean running = true;public void stop() {running = false;}@Overridepublic void run() {while (running) {System.out.println("下載中...");}System.out.println("線程停止");}
}
4.3 中斷線程(Interrupt)
概念:interrupt() 不是直接停止線程,而是發出中斷請求,線程自己決定是否退出。
阻塞線程:sleep()、wait()、join() 會拋 InterruptedException。
非阻塞循環:線程需檢查 isInterrupted() 或結合標志位。
示例:
class DownloadTask implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {try {Thread.sleep(500); // 阻塞操作,可響應中斷} catch (InterruptedException e) {Thread.currentThread().interrupt(); // 重新設置中斷標志break; // 安全退出循環}System.out.println("下載中...");}System.out.println("線程安全停止");}
}Thread t = new Thread(new DownloadTask());
t.start();
Thread.sleep(2000);
t.interrupt(); // 請求停止線程
核心理解:
interrupt() 只是一種請求,不強制停止
循環型任務檢查中斷標志,阻塞任務捕獲異常退出
標志位適合循環任務,interrupt 適合阻塞任務
5. 小結
線程狀態:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
yield():禮貌性讓出 CPU
join():等待線程完成,可帶超時
安全停止線程:
循環任務用 標志位
阻塞任務用 interrupt() + 異常處理
阻塞 vs 非阻塞:阻塞線程可響應 interrupt,非阻塞線程需自己檢查標志