Java 線程通信依賴對象監視器。wait() 釋放鎖並進入等待集,notify() 喚醒等待集中的線程。兩者必須持有同一對象的鎖,否則拋出 IllegalMonitorStateException。
// 原文代碼片段 - 錯誤示範
class ThreadNum extends Thread {
Object o; // 共享對象
public void run() {
synchronized (this) { // 鎖住 ThreadNum 實例
this.wait(); // 在 this 上等待
}
synchronized (this) { // 鎖住 ThreadNum 實例
this.notify(); // 在 this 上通知
}
}
}
class ThreadChar extends Thread {
Object o; // 同一共享對象引用
public void run() {
synchronized (this) { // 鎖住 ThreadChar 實例(不同鎖!)
this.notify();
}
synchronized (this) { // 鎖住 ThreadChar 實例
this.wait();
}
}
}
this 指向不同對象)o 從未被用作鎖wait()/notify() 作用於不同監視器,永無法喚醒對方
public class WaitNotifyDemo {
static final Object lock = new Object(); // 共享鎖對象
static volatile boolean numberTurn = true; // 協調標誌
public static void main(String[] args) {
new Thread(() -> printNumbers(lock)).start();
new Thread(() -> printChars(lock)).start();
}
static void printNumbers(Object lock) {
synchronized (lock) {
for (int i = 1; i <= 26; i++) {
while (!numberTurn) {
try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; }
}
System.out.print(i + " ");
numberTurn = false;
lock.notify();
}
}
}
static void printChars(Object lock) {
synchronized (lock) {
for (char c = 'A'; c <= 'Z'; c++) {
while (numberTurn) {
try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; }
}
System.out.print(c + " ");
numberTurn = true;
lock.notify();
}
}
}
}
lock 對象被兩線程同步while (condition) wait() 防止虛假喚醒notify()每個 Java 對象邏輯上關聯一個監視器:
wait() 釋放鎖並進入的線程隊列wait() 語義:釋放鎖 → 進入等待集 → 休眠。
notify() 語義:從等待集移出一線程 → 進入進入區競爭鎖 → 獲取鎖後從 wait() 返回。
| 組件 | 適用場景 | 優勢 |
|---|---|---|
BlockingQueue | 生產者-消費者 | 內置阻塞/喚醒,無需手動 wait/notify |
CountDownLatch | 一等多/多等一 | 計數器語義清晰,不可重置 |
CyclicBarrier | 多線程匯聚點 | 可重置,支持屏障動作 |
Phaser | 動態階段同步 | 靈活的階段註冊/註銷 |
CompletableFuture | 異步流水線 | 函數式組合,異常傳播 |
Lock/Condition | 精細控制 | 多條件變量、可中斷、公平鎖 |
wait/notify 易錯、難維護,屬於底層基礎設施while 循環檢查條件、volatile 狀態變量Java 線程通信的本質是共享鎖對象上的條件等待與通知。原文示例犯下的「各自鎖各自」錯誤是典型反面教材。現代開發應拥抱 java.util.concurrent 提供的成熟抽象,將同步協調委託給經過驗證的組件,專注於業務邏輯。理解監視器機制、虛假喚醒、內存可見性等底層原理,是正確使用高級工具、排查疑難併發問題的基石。