線程是 Java 並發編程的最小調度單元。本文系統梳理進程與線程區別、線程四大生命週期狀態、兩種創建方式、啟動與運行機制、以及新手高頻誤區,打牢並發基石。
| 維度 | 進程 | 線程 |
|---|---|---|
| 定義 | 執行中的程序,資源分配基本單位 | 進程內的執行路徑,CPU 調度基本單位 |
| 內存 | 獨立地址空間(代碼、數據、堆、棧) | 共享進程堆/方法區,私有棧、程序計數器 |
| 創建/切換開銷 | 大(分配 PCB、頁表、內存映射) | 小(僅棧、寄存器、上下文) |
| 通信 | IPC(管道、Socket、共享內存、消息隊列) | 共享內存直接讀寫、volatile、鎖、隊列 |
| 穩定性 | 崩潰不影響其他進程 | 一線程崩潰可導致整進程退出 |
線程因輕量、共享內存,被稱為「輕量級進程」。
new Thread(),僅分配 Java 對象內存,未請求 OS 線程資源。start(),向 OS 申請線程,進入就緒隊列,等待 CPU 時間片。(含 Running)sleep()、wait()、join() 主動放棄 CPU。synchronized/Lock)。suspend()(已棄用)。run() 執行完返回。stop()(已棄用,極不安全)。
class MyThread extends Thread {
public void run() { System.out.println("Thread 運行"); }
}
new MyThread().start(); // 必須 start(),直接 run() 只是普通方法調用
class MyTask implements Runnable {
public void run() { System.out.println("Runnable 運行"); }
}
new Thread(new MyTask()).start(); // 同一 Task 可被多線程共享,解耦任務與執行
Runnable + Lambda:new Thread(() -> {...}).start();| 誤區 | 正確認知 |
|---|---|
直接調用 run() 即啟動線程 | 必須調用 start() 請求 OS 創建線程,run() 只是主線程同步執行 |
sleep() 釋放鎖 | sleep() 不釋放任何鎖;wait() 釋放監視器鎖 |
stop() 安全終止線程 | stop() 強制釋放鎖導致數據不一致,嚴禁使用;用 interrupt() + 標誌位 |
| 線程優先級決定執行順序 | 優先級僅影響獲取 CPU 概率,不保證順序 |
| 共享變量無需同步 | 多線程讀寫共享變量必須同步(synchronized/volatile/原子類/鎖) |
| start() 可重複調用 | 線程啟動後不可再次 start(),會拋 IllegalThreadStateException |