Java wait()、notify()、notifyAll()方法


wait()

調用wait()方法后,線程進入等待狀態,wait()方法不會返回,直到將來某個時刻,線程從等待狀態被其他線程喚醒后,wait()方法才會返回,然后,繼續執行下一條語句。

wait()方法的執行機制非常復雜,它不是一個普通的Java方法,而是定義在Object類的一個native方法,也就是由JVM的C代碼實現的。

必須在synchronized塊中才能調用wait()方法,因為wait()方法調用時,會釋放線程獲得的鎖wait()方法返回后,線程又會重新試圖獲得鎖。

 

notify()、notifyAll()

this.notifyAll()將喚醒所有當前正在this鎖等待的線程,而this.notify()只會喚醒其中一個(具體哪個依賴操作系統,有一定的隨機性)。這是因為可能有多個線程正在getTask()方法內部的wait()中等待,使用notifyAll()將一次性全部喚醒。通常來說,notifyAll()更安全。有些時候,如果我們的代碼邏輯考慮不周,用notify()會導致只喚醒了一個線程,而其他線程可能永遠等待下去醒不過來了。

但是,注意到wait()方法返回時需要重新獲得this鎖。假設當前有3個線程被喚醒,喚醒后,首先要等待執行addTask()的線程結束此方法后,才能釋放this鎖,隨后,這3個線程中只能有一個獲取到this鎖,剩下兩個將繼續等待。

 

實例

class TaskQueue {
    Queue<String> queue = new LinkedList<>();

    public synchronized void addTask(String s) {
        this.queue.add(s);
        this.notifyAll();
    }

    public synchronized String getTask() throws InterruptedException {
        while (queue.isEmpty()) {
            this.wait();    
        }
        return queue.remove();
    }
}

 

參考資料

廖雪峰Java


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM