一個工作七年的小伙伴,竟然不知道”wait”和“notify”為什麼要在Synchronized代碼塊裡面。 好吧,如果屏幕前的你也不知道,請在評論區打上”不知道“。 對於這個問題,我們來看看普通人和高手的回答。 普通人: 額。。。。。。。。。。。。 高手: wait和notify用來實現多線程之間 ...
一個工作七年的小伙伴,竟然不知道”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帶你學架構
!
如果本篇文章對您有幫助,還請幫忙點個關註和贊,您的堅持是我不斷創作的動力。歡迎關註「跟著Mic學架構」公眾號公眾號獲取更多技術乾貨!