通知后跟另一个通知[重复]

Posted

技术标签:

【中文标题】通知后跟另一个通知[重复]【英文标题】:Notify followed by another notify [duplicate] 【发布时间】:2013-04-03 17:05:32 【问题描述】:

如果您通知一个锁,然后立即再次通知该锁,会发生什么?假设有 2 个或更多线程在等待该锁。是否保证两个线程被唤醒?或者是否有可能只唤醒了一个线程,这意味着第二个通知已经过时了?

lock.notify();
lock.notify();

谢谢!

【问题讨论】:

【参考方案1】:

假设有 2 个或更多线程在等待该锁。是否保证两个线程都被唤醒?

是的。每个通知从等待队列中取出一个线程并将其放入阻塞队列中——被唤醒的线程必须首先访问有问题的synchronized 锁。如果只有 1 个线程在等待锁,那么第二个 notify() 将什么也不做。

重要的是要意识到线程不会立即开始执行。因为它必须在lock 上的synchronized 块中才能执行wait(),它必须再次访问lock 才能运行。块队列中可能已经有多个其他线程,等待访问lock

【讨论】:

第一个在调用第二个 lock.notify 之前唤醒并再次休眠 - 第二个线程不会被唤醒? @Gray:notifynative。你怎么能确定这是行为?为什么不例如第二个notify 不做任何事情,因为notify 带有当前的锁定范围是否已经提升? 因为这不是 Java 规范 @Cratylus。 Object.notify() 有一个与本机实现无关的规范。 @Gray:是的,但是你怎么知道notify 实现“知道”notify 已经被调用所以它什么都不做? 当然@Cratylus,JVM 可能违反规范,但我从未使用过 JVM,其中 2 个调用 notify() 会在等待时释放少于 2 个线程。【参考方案2】:

我怀疑这种行为类似于调用 notifyAll()(在这种情况下,它更像是 notifyTwo())

被唤醒的线程将以通常的方式与任何其他可能正在积极竞争以同步此对象的线程进行竞争;例如,被唤醒的线程在成为下一个锁定该对象的线程时不享有可靠的特权或劣势。

【讨论】:

我认为 OP 关注的是第一个运行的线程抢占调用者的情况,再次循环到等待,因此在调用下一个 notify() 时仍然有两个等待线程。

以上是关于通知后跟另一个通知[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Winforms 通知图标在系统托盘中重复

重复的本地通知

发送apprequest时没有通知[重复]

处理前一个时收到另一个远程通知操作

使用通知传递数据,iphone [重复]

打开另一个通知时,如何防止通知从通知中心消失? iOS