Java 多線程允許單一程式同時執行多個子任務。線程(輕量級進程)是進程內獨立執行單元,共享進程記憶體空間,帶來更好的互動效能與即時控制能力。雖然強大靈活,但正確使用極具挑戰,即使資深開發者也易誤入陷阱。
多線程中,多線程可共享同一程式碼操作不同資料(如會計處理多部門帳目),或各自擁有獨立程式碼與資料。
public class SimpleRunnable implements Runnable {
private final String message;
public SimpleRunnable(String message) {
this.message = message;
}
@Override
public void run() {
for (;;) {
System.out.println(message);
}
}
public static void main(String[] args) {
SimpleRunnable r1 = new SimpleRunnable("Hello");
Thread t1 = new Thread(r1);
t1.start();
}
}
線程啟動從 run() 開始,資料封裝在 Runnable 實例成員中。
覆寫 run(),但佔用唯一繼承名額,靈活度較低。
| 狀態 | 說明 | 轉換方法 |
|---|---|---|
| New (新建) | 建立未啟動 | start() → Runnable |
| Runnable (可執行) | 等待 CPU 時間片 | sleep()/wait()/suspend() → Waiting |
| Waiting (等待/阻塞) | 等待條件滿足 | notify()/resume()/時間到 → Runnable |
| Dead (終止) | run() 結束或 stop() | 不可逆 |
程式僅當所有線程達到 Dead 狀態時才退出。
NORM_PRIORITY)setPriority()/getPriority() 控制ThreadGroup 樹狀結構管理線程集合interrupt()、列舉成員同一時間僅一線程可讀寫共享資料。Java 提供 synchronized 關鍵字:
this(實例)或 Class 物件(靜態)synchronized(obj) { ... } 指定鎖物件,粒度更細資料庫場景:讀多寫少。允許並發讀,寫入獨佔。
class Semaphore {
private static final int EMPTY = 0, READING = 1, WRITING = 2;
private int state = EMPTY;
private int readCount = 0;
public synchronized void readLock() throws InterruptedException {
while (state == WRITING) wait();
state = READING;
readCount++;
}
public synchronized void writeLock() throws InterruptedException {
while (state != EMPTY) wait();
state = WRITING;
}
public synchronized void readUnlock() {
if (--readCount == 0) {
state = EMPTY;
notify();
}
}
public synchronized void writeUnlock() {
state = EMPTY;
notify();
}
}
// 線程 1 // 線程 2
synchronized(lockA) { synchronized(lockB) {
synchronized(lockB) { synchronized(lockA) {
// 互相等待 // 互相等待
} }
}
tryLock(timeout) 避免無限等待ReentrantLock、Semaphore、CountDownLatch 替代低層 synchronized| 優點 | 缺點 |
|---|---|
| 更好的互動與即時效能 | 跨平台行為差異(依賴 OS 調度) |
| 資源共享簡化線程間通訊 | 同步複雜度高,易死鎖、活鎖、飢餓 |
| 利於建模並發業務領域 | 除錯困難,非確定性重現難 |
| 多核 CPU 並行加速計算密集任務 | 線程切換、同步開銷降低效能 |
Java 多線程功能完備但正確使用門檻高。核心在於:共享資料最小化、鎖粒度最小化、鎖順序固定化、優先使用高層並發工具。理解底層原理(Monitor、等待集、狀態轉換)是寫出健壯並發代碼的前提。期待 Java 未來版本持續改進並發模型(如虛擬線程 Project Loom),降低開發者認知負擔。