2010-05-14 61 views
7

爲什麼java.lang.Object有兩種通知方式 - notifynotifyAll?看起來notifyAll至少都是notify所做的一切,那爲什麼不直接用notifyAll?如果使用notifyAll而不是notify,程序是否仍然正確,反之亦然?什麼影響這兩種方法之間的選擇?Java - 何時使用notify或notifyAll?

+0

該問題的接受答案暗示了一個答案 - 差異在於性能,通過使用notifyAll來喚醒無法實際工作的線程僅僅是一個性能問題。所以我認爲這個問題的答案 - notifyAll總是正確的 - 只是沒有表現。 – mdma 2010-05-14 15:49:22

+2

自Java 5(2004年)以來,新增了一個併發庫。 (這個庫實際上要舊得多)我建議你使用這些類,我會勸阻使用notify或notifyAll。 – 2010-05-14 22:19:44

+0

這個問題的答案就在這裏StackOverflow:[Java通知()與notifyAll()](https://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again) 。 – smountcastle 2010-05-14 13:12:25

回答

1

根據的JavaDoc爲notify

喚醒在此對象監視器上等待的單個線程。如果任何線程正在等待這個對象,則選擇其中一個線程來喚醒。這種選擇是任意的,並且由實施決定。線程通過調用其中一個等待方法來等待對象的監視器。

如果您有一個應用程序使用(例如)一個隊列來放置項目,然後有許多工作線程將項目從隊列中取出,這可能很有用。當物品準備就緒後,您可以致電notify喚醒單個工人處理物品。無可否認,這個例子有點做作 - 有可能有更好的方法在Java中實現 - 但你明白了。

1

兩個典型的例子。

假設您有生產者線程和消費者線程。由生產者生產的每個「包」應該由消費者消費。消費者將某些東西放入隊列中,然後調用notify()(只有一個消費者應該被允許處理一個「數據包」。)

假設您想要在漫長的過程完成時收到通知。你想要一個嗶聲和屏幕更新。該過程執行notifyAll()以通知蜂鳴聲和屏幕更新線程。

0

區別在於notify()只會在當前線程上等待一個線程。對於大多數生產者/消費者和委託 - 等待應用程序,這是使用正確的方法。另外,如果只有一個其他線程正在等待當前線程,則不需要通知多於一個等待線程。

相比之下,notifyAll()在所有線程上等待的所有。在每個(相關)睡眠線程必須執行某些操作的情況下,例如響應通知線程所包含的致命或高度重要的事件時,這更有用。

1
//contribute By E.Thulasiram and Team 
    class AA extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    System.out.println("one"); 
    synchronized (a) { 
     try{ 
      a.wait(); 
      System.out.println("one wake up"); 
      this.wait(); 
     }catch(Exception e){ 
      System.out.println(e); 
     } 
    } 
} 
    } 
    class BB extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    System.out.println("two"); 
    synchronized (a) { 
     try{ 
      a.wait(); 
      System.out.println("two wake up"); 
     }catch(Exception e){ 
      System.out.println(e); 
     } 
    } 
} 
    } 
    class CC extends Thread{ 
AA a; 
public void get(AA a){ 
    this.a=a; 
} 
public void run(){ 
    synchronized (a) { 
     a.notifyAll(); 
     System.out.println("NotifyAll"); 
    } 
} 
    } 
    class DD{ 
public static void main(String args[]){ 
    AA a=new AA(); 
    BB b=new BB(); 
    CC c=new CC(); 
    a.get(a); 
    a.start(); 
    b.get(a); 
    b.start(); 
    c.get(a); 
    c.start(); 
} 
    } 
相關問題