單執行緒程式:四個無關任務 (列印、檔案操作、資料庫、繪圖) 循序執行,每個任務含 I/O 等待,總耗時 = 總和。資源利用率極低。
多執行緒:任務並行,等待期可切換執行其他任務,大幅提升吞吐量與回應性。
| 方式 | 進程 | 執行緒 |
|---|---|---|
| 建立開銷 | 大 (獨立記憶體空間、PCB) | 小 (共享進程記憶體、輕量級) |
| 通訊難度 | 高 (IPC: pipe, socket, shared memory) | 低 (共享堆記憶體、同步工具) |
| 穩定性 | 高 (隔離性好) | 較低 (一執行緒崩潰影響全進程) |
| 適用場景 | 獨立服務、安全沙箱 | 高併發、資料共享、即時互動 |
Java 內建執行緒支援,跨平台一致,是首選方案。
class TimePrinter extends Thread {
private int pauseTime;
private String name;
public TimePrinter(int pauseTime, String name) {
this.pauseTime = pauseTime;
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + ": " + new Date());
try { Thread.sleep(pauseTime); } catch (InterruptedException e) {}
}
}
}
// 使用
new TimePrinter(1000, "Thread-A").start();
new TimePrinter(2000, "Thread-B").start();
關鍵: 必須呼叫 start() (啟動新執行緒並呼叫 run()),不可直接呼叫 run() (會在主執行緒同步執行)。
class Task implements Runnable {
public void run() { /* 任務邏輯 */ }
}
new Thread(new Task()).start();
// 或使用執行緒池
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(new Task());
優勢: 解耦任務邏輯與執行緒控制、支援執行緒池、避免單繼承限制。
NEW → RUNNABLE → RUNNING → BLOCKED/WAITING/TIMED_WAITING → TERMINATED
start() 排程器分派 sleep/wait/join/IO run() 結束
// 同步方法
public synchronized void deposit(int amount) {
balance += amount;
}
// 同步區塊 (更精細鎖粒度)
public void withdraw(int amount) {
synchronized (this) {
balance -= amount;
}
}
// 靜態方法鎖定 Class 物件
public static synchronized void staticMethod() { ... }
// 生產者
synchronized (buffer) {
while (buffer.isFull()) buffer.wait(); // 釋放鎖並等待
buffer.add(item);
buffer.notifyAll(); // 喚醒消費者
}
// 消費者
synchronized (buffer) {
while (buffer.isEmpty()) buffer.wait();
Item item = buffer.remove();
buffer.notifyAll(); // 喚醒生產者
}
核心規則:
wait():釋放鎖,進入等待集合notify():喚醒一個等待執行緒notifyAll():喚醒所有等待執行緒 (推薦,避免訊號遺失)class ThreadB extends Thread {
int total;
public void run() {
synchronized (this) {
for (int i = 0; i < 100; i++) total += i;
notify(); // 通知等待者
}
}
}
public class ThreadA {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized (b) { // 鎖定 b 物件
try { b.wait(); } // 釋放 b 的鎖並等待
catch (InterruptedException e) {}
}
System.out.println("Total: " + b.total);
}
}
流程: main 執行緒鎖定 b → 呼叫 wait() 釋放鎖並睡眠 → ThreadB 運行完畢呼叫 notify() → main 重新獲得鎖繼續執行。
ReentrantLock、Condition.await/signal,功能更強ConcurrentHashMap、BlockingQueue、CopyOnWriteArrayListAtomicInteger、LongAdderExecutorService、CompletableFuture (非同步組合)掌握 Thread/Runnable、synchronized、wait/notify 是 Java 並發基石。實務開發優先使用高階並發工具 (JUC 套件),降低同步錯誤風險,提升可維護性。