Java - when to use notify or notifyAll? [duplicate]
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.
精彩评论