同步中,為什麼要wait,又notify誰?

2021-06-21 13:16:01 字數 1284 閱讀 3032

似乎理解起來,wait()是自己停止,等待被喚醒;notify()也是自己停止,通知別人。那麼感覺沒什麼大的區別,不急,先仔細分析他們的來歷。wait()通常執行緒要執行下去需要等待某個條件發生變化,但改變這個條件已經超出了當前方法的控制能力。通常,這種條件由另乙個任務來改變。既然執行不下去,傻等,又改變不了現實,那還不如交出執行權,令當前執行緒掛起,同步資源解鎖,使別的執行緒可以訪問並修改共享資源,自己進行排隊佇列,等候別人的通知。經過測試,好象是先入後出的順序被喚醒的。釋放了鎖意味著另乙個任務可以獲得這個鎖,這一點至關重要,因為這些其他的方法再入處理通常會引起wait()感興趣的變化。wait()和notify()必須包括在synchronized**塊中,等待中的執行緒必須由notify()方法顯式地喚醒,否則它會永遠地等待下去。很多人初級接觸多執行緒時,會習慣把wait()和notify()放在run()方法裡,一定要謹記,這兩個方法屬於某個物件,應在物件所在的類方法中定義它,然後run中去呼叫它。

這裡不得不提下,在object的wait方法是過載的。有三個方法,了解一下除無參之外的另乙個方法wait(毫秒數 n); 這裡毫秒數是指,如果沒有notify通知的情況下,當前被wait執行緒,經過n毫秒之後依然可以回到可執行狀態。如果引數為零,則不考慮實際時間,在獲得通知前該執行緒將一直等待。wait(0, 0) 與 wait(0) 相同。

notify()喚醒正在佇列中等待資源的優先順序最高的執行緒。但它自己不馬上退出資源,繼續執行,等全部執行完了,退出,釋放鎖,這樣才讓wait()的執行緒進入。所以說在物件(當前執行緒具有其鎖定)呼叫notify()方法一定釋放鎖定是只是一廂情願的。至於與notifyall()區別,後者更加安全。使用notify(),在眾多等待同乙個鎖的任務中只有乙個會被喚醒,因此如果你希望使用notify(),就必須保證被喚醒的是恰當的任務。notify()也就是this.notify(),喚醒所有爭搶自己的執行緒,與別的物件產生的wait()沒有關係。

synchronized (a)        

我曾經自己寫過如下非常幼稚的**,寫在public void run()裡邊,目的是在zonerectanglesize < 1的情況下,使自己的執行緒處於阻塞狀態,雖然不會出錯,但這個wait呼叫的是執行緒類物件本身的wait(),畢竟它也是來自object,所以肯定達不到預期的效果:

thread的靜態方法sleep()是不釋放鎖的,也不用操作鎖,所以可以在非同步控制方法和run方法內部呼叫。也就是說當前執行緒即使進入sleep狀態也抱著這把鎖睡覺,保持高度的監控狀態,即使其它執行緒在外邊踢門叫嚷罵娘,他是心安理得,堅決不釋放。如果一直昏睡下去,擁有同一物件資源的執行緒們都會玩完的。但sleep() 允許把機會給其他執行緒不和它搶飯碗的執行緒。

為什麼要執行緒同步

class mythread2 implements runnable catch interruptedexception e system.out.println thread.currentthread getname 賣票,ticket this.ticket else public cla...

為什麼wait和notify方法要在同步塊中呼叫?

public static void main string args throws interruptedexception 報錯 還是報錯 正確的寫法 public static void main string args throws interruptedexception 也就是說wait...

為什麼要執行緒同步的例子

設定全域性變數g bcontinue,在主線程中設定全域性變數g bcontinue,工作執行緒檢測該全域性變數,實現主線程控制工作執行緒的目的 列印出的g cnt1與g cnt2的數值不同,是因為執行緒除錯時時間片的切換 counterror.cpp 定義控制台應用程式的入口點。include s...