Java 每個物件天生擁有一把監視器鎖。wait()、notify()、notifyAll() 定義在 Object 而非 Thread,因為它們操作的是物件的鎖與等待隊列。
synchronized (obj) {
// 前置條件:持有 obj 鎖
obj.wait();
// 1. 釋放 obj 鎖
// 2. 當前線程進入 obj 的等待集合
// 3. 線程狀態:WAITING / TIMED_WAITING
// 4. 被喚醒後:重新競爭 obj 鎖 → 獲得 → 繼續執行
}
synchronized (obj) {
obj.notify();
// 1. 從 obj 等待集合隨機選一線程
// 2. 該線程從 WAITING → BLOCKED(等待鎖)
// 3. 當前線程繼續持有鎖,執行後續程式碼
// 4. 鎖釋放後,被喚醒線程競爭獲得
}
將等待集合中所有線程移至鎖競爭隊列。適用於等待條件不同、或為避免信號丟失的保守策略。
// 錯誤:拋出 IllegalMonitorStateException
obj.wait();
// 正確
synchronized (obj) {
obj.wait();
}
原因:JVM 驗證當前線程是否為鎖持有者,保護等待集合操作的原子性。
synchronized (lock) {
while (!condition) { // 必須用 while,防虛假喚醒
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保留中斷狀態
throw new RuntimeException("線程被中斷", e);
}
}
// 條件滿足,安全執行
doAction();
}
public class SharedContainer {
private final List
public class ProducerConsumerDemo {
public static void main(String[] args) {
SharedContainer container = new SharedContainer();
// 2 生產者 + 2 消費者
for (int i = 0; i < 2; i++) {
new Thread(() -> {
while (true) {
try { container.produce(); Thread.sleep(100); }
catch (InterruptedException e) { break; }
}
}, "Producer-" + i).start();
new Thread(() -> {
while (true) {
try { container.consume(); Thread.sleep(150); }
catch (InterruptedException e) { break; }
}
}, "Consumer-" + i).start();
}
}
}
synchronized (A) {
synchronized (B) {
B.wait(); // 僅釋放 B 的鎖,A 的鎖仍持有!
}
}
這是巢狀同步的巨大陷阱,嚴禁在巢狀 synchronized 中呼叫 wait()。
Linux pthread_cond_wait、Windows ConditionVariable 均可能無信號喚醒。JVM 規範明確允許,必須用 while 迴圈防禦。
// 兩類消費者:消費 A 和 消費 B
// 生產者 notify() 可能喚醒錯誤類型,導致該類型永不被喚醒
// 解決:notifyAll() 或分離鎖物件
ReentrantLock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();
Condition notFull = lock.newCondition();
// 生產者
lock.lock();
try {
while (queue.size() == capacity) notFull.await();
queue.add(item);
notEmpty.signal(); // 精確喚醒消費者
} finally {
lock.unlock();
}
優勢:一把鎖綁定多條件、支援公平鎖、可中斷等待、超時精確控制。
wait/notify/notifyAll 是 Java 併發基石,但易用錯、難除錯、功能受限。掌握其鎖釋放/重獲語意、虛假喚醒、迴圈檢查、巢狀同步陷阱是進階開發者必修課。實戰中優先使用 BlockingQueue、Lock+Condition、Semaphore 等高層工具,將併發複雜度交給專家實現的並發包。