如果一个人在谷歌上搜索“notify()和notifyAll()之间的区别”,那么会跳出很多解释(撇开javadoc段落)。这都归结于被唤醒的等待线程的数量:notify()中有一个,notifyAll()中有所有线程。
然而(如果我确实理解了这些方法之间的区别),只有一个线程总是被选择用于进一步的监视采集;第一种情况是VM选择的线程,第二种情况是系统线程调度程序选择的线程。程序员不知道它们的确切选择过程(在一般情况下)。
那么notify()和notifyAll()之间有什么有用的区别呢?我遗漏了什么吗?
我很惊讶居然没有人提到臭名昭著的“失醒”问题(谷歌it)。
基本上:
如果有多个线程在等待同一个条件,
可以让你从状态A转换到状态B的多个线程,
可以让你从状态B转换到状态A的多个线程(通常是与状态1相同的线程),
从状态A转换到状态B应该通知1中的线程。
然后,您应该使用notifyAll,除非您有可证明的保证,丢失的唤醒是不可能的。
一个常见的例子是并发FIFO队列,其中:
多个排队者(1。和3。)可以将队列从空转换为非空
多个退出队列器(2。上面)可以等待条件“队列不是空的”
Empty ->非空应该通知脱队列者
您可以很容易地编写一个交叉操作,其中从一个空队列开始,2个入队者和2个出队者交互,1个入队者保持休眠状态。
这是一个可以与死锁问题相比较的问题。