如果一个人在谷歌上搜索“notify()和notifyAll()之间的区别”,那么会跳出很多解释(撇开javadoc段落)。这都归结于被唤醒的等待线程的数量:notify()中有一个,notifyAll()中有所有线程。
然而(如果我确实理解了这些方法之间的区别),只有一个线程总是被选择用于进一步的监视采集;第一种情况是VM选择的线程,第二种情况是系统线程调度程序选择的线程。程序员不知道它们的确切选择过程(在一般情况下)。
那么notify()和notifyAll()之间有什么有用的区别呢?我遗漏了什么吗?
这个答案是xagyg的优秀答案的图形重写和简化,包括eran的评论。
为什么要使用notifyAll,即使每个产品都是针对单个消费者的?
考虑生产者和消费者,简化如下。
制作人:
while (!empty) {
wait() // on full
}
put()
notify()
消费者:
while (empty) {
wait() // on empty
}
take()
notify()
假设2个生产者和2个消费者共享一个大小为1的缓冲区。下图描述了一个导致死锁的场景,如果所有线程都使用notifyAll,就可以避免死锁。
每个通知都被标记为被唤醒的线程。