簡體   English   中英

(Java) 線程安全使用 Object wait() 和 notify()

[英](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的鎖,因此您可以對其調用waitnotify 它們都要求當前線程持有 object 上的鎖。

您必須小心您在removeItem中鎖定兩個對象的雙重鎖定。 如果你需要這個,你必須確保你總是以相同的順序鎖定它們,否則,你可能會造成死鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM