多線程中wait()和sleep()以及notify()

多線程中會使用到兩個延遲的函數,wait()和sleep()。一個喚醒函數notify().

  1. wait和notify是Object類中的方法,而sleep是Thread類中的方法。

  2. sleep是Thread類中的靜態方法。無論是在a線程中調用b的sleep方法,還是b線程中調用a的sleep方法,誰調用,誰睡覺。最主要的是sleep方法調用之後,並沒有釋放鎖,sleep是幫助其他線程獲得運行機會的最好方法,但是如果當前線程獲取到的有鎖,sleep不會讓出鎖。使得線程仍然可以同步控制。sleep不會讓出系統資源;而wait是進入線程等待池中等待,讓出系統資源,釋放對象鎖。

  3. 調用wait方法的線程,不會自己喚醒,需要線程調用 notify / notifyAll 方法喚醒等待池中的所有線程,纔會進入就緒隊列中等待系統分配資源。sleep方法會自動喚醒,如果時間不到,想要喚醒,可以使用interrupt方法強行打斷。
    Thread.sleep(0) // 觸發操作系統立刻重新進行一次CPU競爭。

  4. 使用範圍:sleep可以在任何地方使用。而wait,notify,notifyAll只能在同步控制方法或者同步控制塊中使用。

  5. sleep必須捕獲異常,而wait,notify,notifyAll的不需要捕獲異常。若調用wait()沒有持有適當的鎖,執行wait後,會拋出異常IllegalMonitorException,這是個runtimeException的子類,不需要try/catch。

  6. 線程sleep()睡眠到期自動甦醒,並返回到可運行狀態(就緒),不是運行狀態。

  7. sleep()是靜態方法,只能控制當前正在運行的線程.

notify():

notify方法執行後,只有等notify方法的線程將程序執行完,也就是退出synchronized代碼塊或者方法後,當前線程纔會釋放鎖,呈wait狀態的線程纔會獲得該對象的鎖,當wait線程執行完畢後,釋放該線程對象的鎖,此時若該對象沒有再次使用notify語句,即便該對象已經空閒,其他wait狀態等待的線程也沒有得到該對象的通知,還是會繼續阻塞在wait狀態,直到這個對象發出notify或者notifyAll。

notify 和 notifyAll的區別:

notify方法只喚醒一個等待(對象的)線程並使該線程開始執行。所以如果有多個線程等待一個對象,這個方法只會喚醒其中一個線程,選擇哪個線程取決於操作系統對多線程管理的實現。notifyAll 會喚醒所有等待(對象的)線程,儘管哪一個線程將會第一個處理取決於操作系統的實現。如果當前情況下有多個線程需要被喚醒,推薦使用notifyAll 方法。比如在生產者-消費者裏面的使用,每次都需要喚醒所有的消費者或是生產者,以判斷程序是否可以繼續往下執行。

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