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

2021-10-09 06:46:48 字數 1482 閱讀 7675

public

static

void

main

(string[

] args)

throws interruptedexception

報錯

}還是報錯

正確的寫法

public

static

void

main

(string[

] args)

throws interruptedexception

}

也就是說wait和notify方法要在基於同乙個物件的同步塊中使用,那麼這是為什麼呢?

我們先來發出乙個靈魂拷問:什麼時候才需要wait? 什麼時候又需要notify? 我們假設我們要實現乙個堵塞佇列,如果不加同步塊,我們的實現方法可能如下。

class

blockingqueue

public string take()

throws interruptedexception

}

我們在隊列為空的時候使用lock.wait()堵塞,然後有元素新增到佇列的時候再採用lock.notify()喚醒,這段**可能會導致如下問題:

乙個消費者呼叫take,發現buffer.isempty

在消費者呼叫wait之前,由於cpu的排程,消費者執行緒被掛起,生產者呼叫add,然後notify

然後消費者呼叫wait (注意,由於錯誤的條件判斷,導致wait呼叫在notify之後,這是關鍵)

如果很不幸的話,生產者產生了一條訊息後就不再生產訊息了,那麼消費者就會一直掛起,無法消費,那這個佇列就有問題了,會有一條訊息一直無法被消費。

由此看出, 在使用 wait() 和 notify() 這種會掛起執行緒的操作時, 我們需要一種同步機制保證, condition 的檢查與 wait() 操作, 以及 condition 的更新與 notify() 是互斥的。

所以:wait和notify方法要在同步塊中呼叫的根本原因是,這兩個方法存在競態條件。如果不加鎖的話,那麼wait被呼叫的時候可能wait的條件已經不滿足了(如上述)。由於錯誤的條件下進行了wait,那麼就有可能永遠不會被notify到,所以我們需要強制wait/notify在synchronized中

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

似乎理解起來,wait 是自己停止,等待被喚醒 notify 也是自己停止,通知別人。那麼感覺沒什麼大的區別,不急,先仔細分析他們的來歷。wait 通常執行緒要執行下去需要等待某個條件發生變化,但改變這個條件已經超出了當前方法的控制能力。通常,這種條件由另乙個任務來改變。既然執行不下去,傻等,又改變...

wait 和notify 入門例子

也就是說,wait 會讓出物件鎖,同時,當前執行緒休眠,等待被喚醒,如果不被喚醒,就一直等在那兒。notify 並不會讓當前執行緒休眠,但會喚醒休眠的執行緒。先看第乙個例子!public class threadf catch interruptedexception e system.out.pr...

wait和notify造成死鎖的例子

public class threadlocktest implements runnable public static void main string args throws interruptedexception override public void run catch interru...