| 維度 | 進程 | 線程 |
|---|---|---|
| 定義 | 程序的一次執行,擁有獨立內存空間 | 進程內的執行路徑,共享進程內存 |
| 資源開銷 | 大(獨立地址空間、文件句柄等) | 小(僅棧、程序計數器、寄存器) |
| 通信方式 | IPC(管道、Socket、共享內存等) | 共享內存、同步鎖、volatile 等 |
| 切換開銷 | 高(上下文切換涉及 MMU 刷新) | 低(僅寄存器/棧切換) |
| 穩定性 | 進程崩潰不影響其他進程 | 線程崩潰導致整個進程退出 |
java 命令啟動一個 JVM 進程main() 開始執行
┌─────────┐ start() ┌─────────┐
│ NEW │ ──────────────→ │ RUNNABLE│
└─────────┘ └────┬────┘
│ get CPU
▼
┌─────────────┐
│ RUNNING │
└──────┬──────┘
│
┌────────────────────┼────────────────────┐
│ │ │
sleep/wait/join I/O block yield
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ BLOCKED │ │ WAITING │ │ RUNNABLE │
└───────────┘ └───────────┘ └───────────┘
│ │ │
└────────────────────┴────────────────────┘
│
run() ends
▼
┌─────────┐
│ TERMINATED│
└─────────┘
public class Task implements Runnable {
@Override
public void run() {
System.out.println("執行線程: " + Thread.currentThread().getName());
}
}
// 使用
Runnable task = new Task();
new Thread(task, "Thread-A").start();
new Thread(task, "Thread-B").start(); // 同一任務實例可被多線程共享
優勢:避免單繼承限制、任務與線程分離、支持線程池提交、可共享任務實例。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("執行線程: " + getName());
}
}
// 使用
new MyThread().start(); // 必須調用 start() 而非 run()
劣勢:繼承 Thread 佔用了繼承名額,任務與線程耦合。
// Runnable + Lambda
new Thread(() -> {
System.out.println("Lambda 線程: " + Thread.currentThread().getName());
}, "Lambda-Thread").start();
// 線程池提交(生產環境推薦)
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> System.out.println("線程池任務"));
executor.shutdown();
Java 多線程核心在於 Runnable 任務封裝 + Thread 執行載體 + 線程池管理。理解進程/線程區別、狀態流轉、創建方式優劣,是編寫高併發、高性能 Java 應用的基石。生產環境務必使用線程池(ThreadPoolExecutor)統一管理線程生命周期,避免頻繁創建銷毀開銷與 OOM 風險。