一個工作七年的小夥伴,竟然不知道”wait”和“notify”為什麼要在Synchronized程式碼塊裡面。
好吧,如果螢幕前的你也不知道,請在評論區打上”不知道“。
對於這個問題,我們來看看普通人和高手的回答。
普通人:
額。。。。。。。。。。。。
高手:
- wait和notify用來實現多執行緒之間的協調,wait表示讓執行緒進入到阻塞狀態,notify表示讓阻塞的執行緒喚醒。
- wait和notify必然是成對出現的,如果一個執行緒被wait()方法阻塞,那麼必然需要另外一個執行緒通過notify()方法來喚醒這個被阻塞的執行緒,從而實現多執行緒之間的通訊。
在多執行緒裡面,要實現多個執行緒之間的通訊,除了管道流以外,只能通過共享變數的方法來實現,也就是執行緒t1修改共享變數s,執行緒t2獲取修改後的共享變數s,從而完成資料通訊。
但是多執行緒本身具有並行執行的特性,也就是在同一時刻,多個執行緒可以同時執行。在這種情況下,執行緒t2在訪問共享變數s之前,必須要知道執行緒t1已經修改過了共享變數s,否則就需要等待。
同時,執行緒t1修改過了共享變數S之後,還需要通知在等待中的執行緒t2。
所以要在這種特性下要去實現執行緒之間的通訊,就必須要有一個競爭條件控制執行緒在什麼條件下等待,什麼條件下喚醒。
- 而Synchronized同步關鍵字就可以實現這樣一個互斥條件,也就是在通過共享變數來實現多個執行緒通訊的場景裡面,參與通訊的執行緒必須要競爭到這個共享變數的鎖資源,才有資格對共享變數做修改,修改完成後就釋放鎖,那麼其他的執行緒就可以再次來競爭同一個共享變數的鎖來獲取修改後的資料,從而完成執行緒之前的通訊。
- 所以這也是為什麼wait/notify需要放在Synchronized同步程式碼塊中的原因,有了Synchronized同步鎖,就可以實現對多個通訊執行緒之間的互斥,實現條件等待和條件喚醒。
- 另外,為了避免wait/notify的錯誤使用,jdk強制要求把wait/notify寫在同步程式碼塊裡面,否則會丟擲IllegalMonitorStateException
- 最後,基於wait/notify的特性,非常適合實現生產者消費者的模型,比如說用wait/notify來實現連線池就緒前的等待與就緒後的喚醒。
以上就是我對wait/notify這個問題的理解。
總結
這個是一個典型的經典面試題。
其實考察的就是Synchronized、wait/notify的設計原理和實現原理。
由於wait/notify在業務開發整幾乎不怎麼用到,所以大部分人回答不出來。
其實併發這塊內容理論上來說所有程式設計師都應該要懂,不管是它的應用價值,還是設計理念,非常值得學習和借鑑。
本期的普通人VS高手面試系列就到這裡結束了,喜歡的朋友記得點贊和收藏。
另外,有任何技術上的問題,職業發展有關的問題,都可以私信我,我會在第一時間回覆。
版權宣告:本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自Mic帶你學架構
!
如果本篇文章對您有幫助,還請幫忙點個關注和贊,您的堅持是我不斷創作的動力。歡迎關注同名微信公眾號獲取更多技術乾貨!