为什么java.lang.Object
有两种通知方式 - notify
和notifyAll
?似乎notifyAll
至少做了notify
所做的一切,为什么不一直只使用notifyAll
?如果使用notifyAll
代替notify
,程序是否仍然正确,反之亦然?是什么影响了这两种方法之间的选择?
答案 0 :(得分:2)
//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();
}
}
答案 1 :(得分:1)
根据notify
的JavaDoc:
唤醒正在此对象监视器上等待的单个线程。如果任何线程正在等待此对象,则选择其中一个线程被唤醒。选择是任意的,由实施决定。线程通过调用其中一个等待方法等待对象的监视器。
如果您的应用程序使用(例如)队列放置项目,然后有许多工作线程将项目从队列中拉出来,那么这可能很有用。当项目准备就绪时,您可以调用notify
唤醒单个工作人员来处理该项目。不可否认,这个例子有点人为 - 有可能更好的方法在Java中实现它 - 但你明白了。
答案 2 :(得分:1)
两个典型的例子。
假设你有一个生产者线程和一个消费者线程。生产者生产的每个“包”应由消费者消费。消费者将某些东西放入队列然后调用notify()
(只有一个消费者应该通过处理一个“数据包”。)
假设您希望在漫长的过程结束时收到通知。你想要一个哔哔声和一个屏幕更新。该进程执行notifyAll()
以通知蜂鸣线程和屏幕更新线程。
答案 3 :(得分:-1)
不同之处在于notify()
仅重击等待当前线程的一个线程。对于大多数生产者/消费者和委托和等待应用程序,这是正确的使用方法。此外,如果只有一个其他线程在当前线程上等待,则不需要通知多个等待线程。
相反,notifyAll()
重击等待当前线程的其他线程的所有。这在每个(相关的)休眠线程必须执行某些操作的情况下更有用,例如响应通知线程所包含的致命或高重要性事件。