作者:Yujiaao
https://segmentfault.com/a/1190000019962661
一個有難度的 Java 問題,wait 和 notify,
它們是在有 synchronized 標記的方法或 synchronized 塊中呼叫的,因為 wait 和 nodify 需要監視對其呼叫的 Object,
大多數Java開發人員都知道物件類的 wait(),notify() 和 notifyAll() 方法必須在 Java 中的 synchronized 方法或 synchronized 塊中呼叫, 但是我們想過多少次, 為什么在 Java 中 wait, notify 和 notifyAll 來自 synchronized 塊或方法?
最近這個問題在Java面試中被問到我的一位朋友,他思索了一下,并回答說: 如果我們不從同步背景關系中呼叫 wait() 或 notify() 方法,我們將在 Java 中收到 IllegalMonitorStateException,
他的回答從實際效果上是正確的,但面試官對這樣的答案不會完全滿意,并希望向他解釋這個問題,面試結束后他和我討論了這個問題,我認為他應該告訴面試官關于 Java 中 wait()和 notify()之間的競態條件,如果我們不在同步方法或塊中呼叫它們就可能存在,
讓我們看看競態條件如何在 Java 程式中產生,它也是流行的執行緒面試問題之一,

為什么要等待來自 Java中的 synchronized 方法的 wait方法為什么必須從 Java 中的 synchronized 塊或方法呼叫 ?
我們主要使用 wait(),notify() 或 notifyAll() 方法用于 Java 中的執行緒間通信,一個執行緒在檢查條件后正在等待,例如,在經典的生產者 - 消費者問題中,如果緩沖區已滿,則生產者執行緒等待,并且消費者執行緒通過使用元素在緩沖區中創建空間后通知生產者執行緒,
呼叫notify() 或 notifyAll() 方法向單個或多個執行緒發出一個條件已更改的通知,并且一旦通知執行緒離開 synchronized 塊,正在等待的所有執行緒開始獲取正在等待的物件鎖定,幸運的執行緒在重新獲取鎖之后從 wait() 方法回傳并繼續進行,
讓我們將整個操作分成幾步,以查看Java 中 wait() 和 notify() 方法之間的競爭條件的可能性,我們將使用Produce Consumer 執行緒示例更好地理解方案:
-
Producer 執行緒測驗條件(緩沖區是是否已滿)并確認是否需要等待(如果發現緩沖區已滿則需要等待),
-
Consumer 執行緒在使用緩沖區中的元素后,設定條件,
-
Consumer 執行緒呼叫 notify() 方法; 這是不會被聽到的,因為 Producer 執行緒還沒有等待,
-
Producer 執行緒呼叫 wait() 方法并進入等待狀態,
因此,由于競態條件,我們可能會丟失通知,如果我們使用緩沖區或只使用一個元素,生產執行緒將永遠等待,你的程式將掛起,
“在Java 同步中等待 notify 和 notifyAll 現在讓我們考慮如何解決這個潛在的競態條件?這個競態條件通過使用 Java 提供的 synchronized 關鍵字和鎖定來解決,為了呼叫 wait(),notify() 或 notifyAll(),必須獲得對我們呼叫方法的物件的鎖定,
由于 Java 中的 wait() 方法在等待之前釋放鎖定并在從 wait() 回傳之前重新獲取鎖定方法,我們必須使用這個鎖來確保檢查條件(緩沖區是否已滿) 和設定條件 (從緩沖區獲取元素) 是原子的,這可以通過使用 synchronized 方法或塊來實作,
我不確定這是否是面試官實際期待的,但這個我認為至少有意義,請糾正我如果我錯了,請告訴我們是否還有其他令人信服的理由呼叫 wait(),notify() 或 Java 中的 notifyAll() 方法,
總結一下,我們用 Java 中的 synchronized 方法或 synchronized 塊呼叫 Java 中的 wait(),notify() 或 notifyAll() 方法來避免:
-
Java 會拋出
IllegalMonitorStateException,如果我們不呼叫來自同步背景關系的wait(),notify()或者notifyAll()方法, -
Javac 中 wait 和 notify 方法之間的任何潛在競爭條件,
關注公眾號Java技術堆疊回復"面試"獲取我整理的2020最全面試題及答案,
推薦去我的博客閱讀更多:
1.Java JVM、集合、多執行緒、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架構、阿里巴巴等大廠最新面試題
覺得不錯,別忘了點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/144560.html
標籤:Java
