如果有人在谷歌上搜索"notify()notifyAll()之间的差异",那么会弹出很多解释(不包括javadoc段落).这一切都归结为正在唤醒的等待线程的数量:每notify()个线程中就有一个线程被唤醒,每notifyAll()个线程中就有一个线程被唤醒.

然而(如果我正确理解了这些方法之间的差异),只有一个线程总是被 Select 用于进一步的监视器采集;在第一种情况下是由VM Select 的,在第二种情况下是由系统线程调度器 Select 的.程序员不知道这两种方法(在一般情况下)的确切 Select 过程.

那么notify()notifyAll()之间有什么区别呢?我错过什么了吗?

推荐答案

然而(如果我正确理解了这些方法之间的区别),只有一个线程总是被 Select 用于进一步的监视器采集.

这是不对的.o.notifyAll()唤醒o.wait()次呼叫中被阻止的all个线程.线程只能从o.wait()一个接一个地返回,但每个线程都有自己的轮到.


简单地说,这取决于线程等待通知的原因.你是想告诉一个等待的线程发生了什么事,还是想同时告诉所有线程?

在某些情况下,等待结束后,所有等待线程都可以采取有用的操作.例如,一组等待某个任务完成的线程;一旦任务完成,所有等待的线程都可以继续它们的事务.在这种情况下,您可以使用notfyAll()同时唤醒所有等待的线程.

另一种情况,例如互斥锁定,只有一个等待的线程在收到通知后才能执行有用的操作(在本例中,获取锁).在这种情况下,您宁愿使用notify().如果实现得当,在这种情况下,也可以使用notifyAll(),但不必要地唤醒那些无论如何都不能做任何事情的线程.


在许多情况下,等待条件的代码将被编写为循环:

synchronized(o) {
    while (! IsConditionTrue()) {
        o.wait();
    }
    DoSomethingThatOnlyMakesSenseWhenConditionIsTrue_and_MaybeMakeConditionFalseAgain();
}

这样,如果一个o.notifyAll()调用唤醒了多个正在等待的线程,并且第一个从o.wait() make返回的线程将状态保持为false,那么被唤醒的其他线程将返回等待状态.

Java相关问答推荐

如何让TaskView总是添加特定的列来进行排序?

当一个链表中间有一个循环时,它的松散部分会发生什么?

无法找到符号错误—Java—封装

我想了解Java中的模块化.编译我的应用程序时,我有一个ResolutionException

有没有一种方法使保持活动设置专用于java.net.http.HttpClient的一个实例

如何创建同一类的另一个对象,该对象位于变量中?

为什么我的在一个范围内寻找素数的程序不能像S所期望的那样工作

在Spring Boot中使用哪个Java类来存储创建时间戳?

JDK 21-为什么线程局部随机S nextInt不直接用Super.nextInt实现?

Jolt变换JSON数组问题

除0错误/抱歉我的句子是PT

如何在运行docker的应用程序中获取指定的配置文件

JavaFX复杂项目体系 struct

Win32函数的JNA绑定DwmGetColorizationColor返回E_INVALIDARG错误

如何将RESTAssured';S的Http标题转换为<;字符串、字符串和>的映射?

如何使用Java ZoneID的区域设置?

rest api服务 spring 启动中出现IllegalFormatConversionException

ControlsFX RangeSlider在方向垂直时滞后

java构造函数中的冻结操作何时发生?

java.util.LinkedList()是如何成为MutableList的实例的?