小談Java中notify() 和 notifyAll()的細微區別

之前博主的一份作業中涉及到Java的簡單併發,主要是用synchronized,wait(),notify(),notifyAll()來控制多線程的正確運行。

這份作業中有個知識點稍微令我感覺混亂,那就是notify()和notifyAll()的區別。notify()會隨機喚醒一個正在等待的線程,而notifyAll()會喚醒所有正在等待該對象的線程。但是由於synchronized這個關鍵字,無論是notify()還是notifyAll(),最終都只會有一個線程進入運行態(在該對象鎖可用的情況下)。

那notify()和notifyAll()有什麼區別呢?

答案是調用notify()後只有一個線程會被喚醒,其他等待該對象鎖的線程依然會處於wait()中。

對象鎖而調用notifyAll()後所有等待該對象鎖的線程都會結束wait()轉而去競爭對象鎖,而沒有搶到對象鎖的線程會回到等待狀態(這裏的等待狀態是線程的一個狀態),這時候線程只需要拿到對象鎖就可以運行,而不需要再次被notify

由於這個特性,當不同線程等待同一個對象鎖,但是需要在不同的條件下繼續運行時,就可以用while(check){wait();} 和notifyAll()來確保正確喚醒你所期待被喚醒的那個線程。

換而言之,如果這個時候(即有多個線程等待同一個對象鎖,但是不同線程被喚醒的條件不同時)使用notify()而不用while(check){wait();} 和notifyAll()那麼就有可能導致錯誤的喚醒從而使程序錯運行。


總結: notify()使一個(或零個)線程從等待隊列進入鎖池。

        notifyAll()使等待隊列中的所有等待該對象鎖的線程進入鎖池 。 

        可以用while(check){wait();} 和notifyAll()來確保喚醒正確的那個線程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章