wait, notify, notifyAll 是多線程之間通訊最重要的 3 個方法,今天,棧長給你們普及一下它們的知識要點及應用實戰。java
wait:讓持有該對象鎖的線程等待;多線程
notify: 喚醒任何一個持有該對象鎖的線程;線程
notify: 喚醒全部持有該對象鎖的線程;code
它們 3 個的關係是,調用對象的 wait 方法使線程暫停運行,經過 notify/ notifyAll 方法喚醒調用 wait 暫時的線程。對象
然而,它們並非 Thread 類中的方法,而是 Object 類中的,爲何呢!? 由於每一個對象都有監視鎖,線程要操做某個對象固然是要獲取某個對象的鎖了,而不是線程的鎖。blog
如圖所示,wait 帶時間表示最大超時時間,過了時間還不喚醒就會自動喚醒線程從新競爭對象鎖。資源
一、調用對象的 wait, notify, notifyAll 方法須要擁有對象的監視器鎖,即它們只能在同步方法(塊)中使用;get
二、調用 wait 方法會使用線程暫停並讓出 CPU 資源,同時釋放持有的對象的鎖;同步
三、多線程使用 notify 容易發生死鎖,通常使用 notifyAll;it
四、關於 wait 和 sleep 的詳細區別請翻閱 《多線程 sleep 和 wait 的 5 個區別》這篇文章。
/** * 公衆號:Java技術棧 */ public static void main(String[] args) { Object lock = new Object(); Thread t1 = new Thread(() -> { synchronized (lock) { for (int i = 0; i < 20; i++) { System.out.print(i); if (i == 10) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); Thread t2 = new Thread(() -> { synchronized (lock) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("Java技術棧"); lock.notifyAll(); } }); t1.start(); t2.start(); }
上面的例子結合 wait/ notifyAll 來演示了它們的相互做用。
線程 t1 首先輸出 012345678910
,5秒後繼續輸出 Java技術棧111213141516171819
。
更多 Java 多線程技術文章請在Java技術棧公衆號後臺回覆關鍵字:多線程。
本文原創首發於公衆號:Java技術棧(id:javastack),關注公衆號在後臺回覆 "多線程" 可獲取更多,轉載請原樣保留本信息。