[英](Java) Thread safety using Object wait() and notify()
我一直在尋找一種方法讓一個線程等待/休眠,直到另一個線程發出信號表明某事已准備就緒。 等待的線程應該喚醒,處理可用的數據,然后 go 回到睡眠狀態,直到另一個線程再次發出信號。
The simplest method I could find was Object.wait()
and Object.notify()
, which behaved like a semaphore initialised to value 0. However, without the synchronized
statements around notify/wait
, Java always threw IllegalMonitorStateException
when the thread was not the監控所有者。 所以我只是把它們放在代碼周圍,如下所示。
線程1:運行無限循環
public class Main {
private Handler handler; // only one instance (singleton pattern)
public void listen() {
while (true) {
try {
synchronized (handler) {
handler.wait();
int value = handler.getSize();
// do something
}
} catch (InterruptedException e) {
// ...
}
}
}
}
線程 2:其他一些 class 調用 removeItem
public class Handler {
// SINGLETON PATTERN - ONLY ONE INSTANCE
private ArrayList<Integer> sharedList;
private Handler() {
sharedList = new ArrayList<>();
}
public void addItem(Integer i) {
synchronized (sharedList) {
// add to list
}
}
public void removeItem(int i) {
synchronized (sharedList) {
// remove item
// notify that something is removed
synchronized (this) {
this.notify(); // this == handler
}
}
}
public int getSize() {
synchronized (sharedList) {
return sharedList.size();
}
}
}
它似乎工作得很好,但不確定是否存在隱藏的錯誤。 我的問題是:這安全嗎? wait
是否釋放handler/this
的實例鎖,以便notify
可以獲取鎖?
同步塊是安全的。 語句synchronized(obj)
獲取參數obj
的鎖,因此您可以對其調用wait
和notify
。 它們都要求當前線程持有 object 上的鎖。
您必須小心您在removeItem
中鎖定兩個對象的雙重鎖定。 如果你需要這個,你必須確保你總是以相同的順序鎖定它們,否則,你可能會造成死鎖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.