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

Java 並發 Wait-Notify 機制深度解析:狀態變量、條件斷言、條件隊列與標準模板

     編輯:Java 相關知識

wait/notify 是 Java 同步機制的基石,構建生產者-消費者、線程池、鎖框架的核心原語。本文從狀態變量、條件斷言、條件隊列三大概念切入,嚴謹定義 wait/notify/notifyAll 的語義規則,給出循環檢查模板並針對虛假喚醒、多條件共享鎖、多線程競爭三大場景深度剖析循環的必要性。

核心三概念

  1. 狀態變量: 線程等待的前提條件承載體(如隊列大小、標誌位)。
  2. 條件斷言: 判斷狀態變量是否滿足繼續執行的邏輯表達式(如 queue.size() < capacity)。
  3. 條件隊列: 每個對象內置的等待線程集合,wait() 將當前線程加入,notify() 從中喚醒。

六大鐵律(必讀)

  1. 屬於 Object,每個對象天然擁有鎖與條件隊列。
  2. 調用前必須持有對象鎖 → 必須在 synchronized(obj) 中。
  3. wait() 釋放鎖並進入條件隊列;notify() 隨機喚醒一個;notifyAll() 喚醒全部。
  4. 喚醒後需重新獲取鎖才能繼續執行 wait() 之後的代碼。
  5. 喚醒線程與持有鎖線程互斥:notify() 執行時鎖仍被持有,被喚醒線程只能在鎖釋放後競爭。
  6. 虛假喚醒 存在:無通知、中斷、超時也可能醒來,必須循環檢查條件斷言。

標準等待模板(背誦級)

synchronized(obj) {
    while (!conditionPredicate) {  // 循環而非 if
        obj.wait();                // 釋放鎖、進隊列、掛起
    }
    // 條件滿足,安全執行業務邏輯
}

為什麼必須用 while 循環?

場景若用 if 後果while 保護機制
一把鎖保護多狀態變量被喚醒線程可能檢查錯誤條件,繼續執行導致邏輯錯誤醒來重新檢查自身條件,不滿足繼續 wait
多線程等待同一條件notifyAll 喚醒所有,只有一個能搶到資源,其餘若不檢查會錯誤執行搶不到資源的線程檢查失敗,繼續 wait
虛假喚醒無故醒來直接執行業務邏輯,嚴重 Bug條件不滿足,循環回去 wait

升級建議

JDK 1.5+ 推薦使用 Lock + Condition:
Lock lock = new ReentrantLock(); Condition notFull = lock.newCondition();
精確綁定條件隊列,避免多條件共用一把鎖的混淆,API 更語義化。

掌握 Wait-Notify 本質,是通往高性能並發組件開發的必經之路。

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