为什么wait、notify必须在synchronized保护的同步代码中
生活随笔
收集整理的這篇文章主要介紹了
为什么wait、notify必须在synchronized保护的同步代码中
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先思考如果wait、notify不在synchronized保護的同步代碼中的樣子:
//經典的生產者與消費者
public class BlockingQueue{Queue<String> buffer=new LinkedList<String>();//負責往buffer中添加數據,添加完后執行notify喚醒之前等待的線程。public void give(String data){buffer.add(data);notify(); }// 負責檢查整個buffer是否為空,如果為空,就等待;否則,就取出一個數據。public String take() throws InterruptedException{while(buffer.isEmpty()){wait();}return buffer.remove; } }以上代碼沒有受synchronized保護,可能會發生以下情況:
- 首先,消息者線程調用take()方法并判斷buffer.isEmpty方法是否返回true,為true代表buffer是空的,則線程進入等待狀態。但是在線程調用wait方法之前,就被調度器暫停了,而此時還未來得及執行wait方法
- 其次,生產者執行整個give方法,并執行了notify方法,但是沒有任何效果,因為take()方法的wait還沒有執行。
再次,執行被調度器暫停的消費者線程,繼續執行wait方法,等待中。因為 buffer.isEmpyt、wait,即判斷與執行不是一個原子操作,它在中間被打破了,是線程不安全的。 - 最后,如果此時沒有更多的生產者進行生產,那么消費者便可能陷入無窮的等待中,因為其剛才錯過了notify方法。
因此,應該在兩個方法前加synchronized關鍵字,獲得對象的鎖monitor。 否則,拋出IllegalMonitorStateException異常,wait、notify間也存在潛在的競態條件。
總結
以上是生活随笔為你收集整理的为什么wait、notify必须在synchronized保护的同步代码中的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 外卖红包深度研究报告:千亿市场下的公号私
- 下一篇: 理清ThreadLocal、Thread