简短的总结:
总是更喜欢使用notifyAll()而不是notify(),除非你有一个大型并行应用程序,其中大量线程都在做同样的事情。
解释:
notify()[…醒来时还是单身
线程。因为notify()不允许指定线程
唤醒后,它只在大规模并行应用程序中有用
是指具有大量线程的程序,它们都执行类似的任务。
在这样的应用程序中,您不关心哪个线程被唤醒。
来源:https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
比较上述情况下的notify()和notifyAll():一个大型并行应用程序,其中线程在做相同的事情。如果在这种情况下调用notifyAll(), notifyAll()将导致大量线程的唤醒(即调度),其中许多线程是不必要的(因为实际上只有一个线程可以继续,即被授予wait()、notify()或notifyAll()对象监视的线程被调用),因此浪费计算资源。
因此,如果您的应用程序中没有大量线程并发地做同样的事情,请使用notifyAll()而不是notify()。为什么?因为,正如其他用户已经在这个论坛上回答的那样,notify()
唤醒正在此对象的监视器上等待的单个线程。[…]
选择是任意的,发生在自由裁量权
实现。
来源:Java SE8 API (https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notify--)
Imagine you have a producer consumer application where consumers are ready (i.e. wait() ing) to consume, producers are ready (i.e. wait() ing) to produce and the queue of items (to be produced / consumed) is empty. In that case, notify() might wake up only consumers and never producers because the choice who is waken up is arbitrary. The producer consumer cycle wouldn't make any progress although producers and consumers are ready to produce and consume, respectively. Instead, a consumer is woken up (i.e. leaving the wait() status), doesn't take an item out of the queue because it's empty, and notify() s another consumer to proceed.
In contrast, notifyAll() awakens both producers and consumers. The choice who is scheduled depends on the scheduler. Of course, depending on the scheduler's implementation, the scheduler might also only schedule consumers (e.g. if you assign consumer threads a very high priority). However, the assumption here is that the danger of the scheduler scheduling only consumers is lower than the danger of the JVM only waking up consumers because any reasonably implemented scheduler doesn't make just arbitrary decisions. Rather, most scheduler implementations make at least some effort to prevent starvation.