开发者

Java - when to use notify or notifyAll? [duplicate]

This question already has answers here: Java: notify() vs. notifyAll() all over again 开发者_StackOverflow (26 answers) Closed 5 years ago.

Why does java.lang.Object have two notify methods - notify and notifyAll? It seems that notifyAll does at least everything notify does, so why not just use notifyAll all the time? If notifyAll is used instead of notify, is the program still correct, and vice versa? What influences the choice between these two methods?


Two simple examples:

  • Let's say you have a producer thread and a consumer thread. Each "packet" produced by the producer should be consumed by a consumer. The consumer puts something in a queue and then calls notify() (Only one consumer should be let through to process one "packet".)

  • Let's say you want to have a notification when a lengthy process has finished. You want a beep and a screen update. The producer performs notifyAll() to notify both the beeping-thread and the screen-update-thread.


According to the JavaDoc for notify:

Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.

This might be useful if you had an application that uses, for example, a queue to place items and then has many worker threads that will pull items off of the queue. When an item is ready, you could call notify to wake up a single worker to process the item. Admittedly this example is a bit contrived - there are likely better ways to implement this in Java - but you get the idea.


  //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();
}
    }


The difference is that notify() thumps only the one thread waiting on the current thread. For most producer/consumer and delegate-and-wait applications, this is the proper method to use. Also, if only one other thread is waiting on the current thread, there is no need to notify more than that one waiting thread.

In contrast, notifyAll() thumps all of the other threads waiting on the current thread. This is more useful in situations where every (related) sleeping thread must do something, such as in response to a fatal or high-importance event enccountered by the notifying thread.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜