線程是進程中的一個實體,是系統獨立調度和分派的基本單位。線程自身不擁有系統資源,僅擁有運行必需的資源(程序計數器、棧、局部變量),但可與同進程的其他線程**共享進程的所有資源**(堆內存、文件句柄、全局變量等)。
| 維度 | 進程 | 線程 |
|---|---|---|
| 資源擁有 | 獨立地址空間、獨立資源 | 共享進程資源,僅有私有棧/PC |
| 調度單位 | 否(作為容器) | 是(CPU 調度基本單位) |
| 創建/銷毀開銷 | 大(需分配地址空間、載入資源) | 小(輕量級進程) |
| 通信方式 | IPC(管道、Socket、共享內存) | 直接讀寫共享變量(需同步) |
| 穩定性 | 崩潰不影響其他進程 | 一線程崩潰可能導致整進程退出 |
new Thread(),未調用 start()。start() 後,等待 CPU 調度。run() 方法體。sleep())、wait()、join()。run() 正常返回、拋出未捕獲異常、調用 stop()(已棄用)。狀態轉換:新建 → 就緒 ↔ 運行 → 死亡;運行 → 阻塞 → 就緒。
MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10。setPriority() / getPriority() 設置獲取,**但不可依賴優先級實現業務邏輯正確性**(不同 JVM/OS 實現差異大)。interrupt()、setDaemon()、enumerate())。setDaemon(true) 必須在 start() 前調用;isDaemon() 判斷。class MyThread extends Thread {
@Override
public void run() {
// 線程執行體
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
}
public static void main(String[] args) {
new MyThread().start(); // 必須調用 start(),而非 run()
}
}
class MyTask implements Runnable {
@Override
public void run() {
// 線程執行體
}
public static void main(String[] args) {
Thread t = new Thread(new MyTask());
t.start();
}
}
ExecutorService.submit(Runnable)、FutureTask、CompletableFuture 皆接受 Runnable/Callable。| 方法 | 說明 | 狀態影響 |
|---|---|---|
start() | 啟動線程,JVM 調用 run() | 新建 → 就緒 |
run() | 線程執行體,**直接調用不會開新線程** | — |
sleep(ms) | 靜態方法,讓當前線程睡眠,**不釋放鎖** | 運行 → 阻塞 |
yield() | 讓出 CPU,重新參與調度,**不保證成功** | 運行 → 就緒 |
join() | 等待該線程結束 | 調用者阻塞 |
interrupt() | 打斷阻塞/睡眠,設置中斷標誌 | 拋出 InterruptedException |
stop()/suspend()/resume() | 已棄用,不安全,易導致數據不一致 | — |
isAlive() | 判斷線程是否存活(已啟動未死亡) | — |
Executors / ThreadPoolExecutor。Callable + Future 獲取返回值,或 CompletableFuture 異步編排。ReentrantLock、CountDownLatch、CyclicBarrier、Semaphore、Phaser。ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue 實現類。volatile 濫用,理解 happens-before 規則。線程是 Java 併發的基石。掌握「生命週期、調度、同步、協作」四大核心,拋棄 Thread 繼承轉向 Runnable + 線程池,再配合 JUC 包豐富工具,才能寫出高效、安全、可維護的併發程序。