首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 線程通信機制:wait/notify 詳解與實戰

     編輯:Java 綜合教學

線程通信核心概念

當多個線程共享同一把鎖對象時,透過 wait()、notify()、notifyAll() 可實現線程間的協作與同步。典型場景:生產者-消費者模型、線程順序執行控制。

關鍵方法語義

方法行為鎖狀態
wait()當前線程進入等待集,釋放鎖釋放
notify()隨機喚醒一個等待線程,移入鎖池持有
notifyAll()喚醒所有等待線程,全部移入鎖池持有

經典範例:線程 A 執行到一半讓位給 B,B 完成後喚醒 A

共享鎖對象

Object lock = new Object();

線程 A:執行到 i=5 時 wait()

class ThreadA extends Thread {
    private final Object lock;
    ThreadA(Object lock) { this.lock = lock; }
    
    public void run() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                System.out.println(getName() + "---" + i);
                if (i == 5) {
                    try { lock.wait(); } 
                    catch (InterruptedException e) { e.printStackTrace(); }
                }
            }
        }
    }
}

線程 B:執行到 i=2 時 notify()

class ThreadB extends Thread {
    private final Object lock;
    ThreadB(Object lock) { this.lock = lock; }
    
    public void run() {
        synchronized (lock) {
            for (int i = 0; i < 10; i++) {
                System.out.println(getName() + "---" + i);
                if (i == 2) lock.notify();
            }
        }
    }
}

啟動測試

public static void main(String[] args) {
    Object lock = new Object();
    new ThreadA(lock).start();
    new ThreadB(lock).start();
}

輸出結果分析

A---0 ... A---5
B---0 B---1 B---2  ← notify() 喚醒 A
B---3 ... B---9    ← B 持有鎖繼續跑完
A---6 ... A---9    ← B 釋放鎖後 A 獲取鎖繼續

關鍵注意事項

  • 必須在 synchronized 區塊中調用,否則拋出 IllegalMonitorStateException
  • wait() 釋放鎖,sleep() 不釋放鎖
  • 喚醒後需重新競爭鎖,不會立即執行
  • 生產者-消費者模式建議用 while 而非 if 判斷條件,防止虛假喚醒

現代替代方案

Java 5+ 推薦使用 java.util.concurrent 套件:

  • BlockingQueue 實現生產消費
  • CountDownLatch/CyclicBarrier 控制執行順序
  • Condition 替代 wait/notify,支援多條件隊列

理解 wait/notify 底層機制,有助於排查併發 Bug 與閱讀框架源碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved