【发布时间】:2010-09-07 09:54:00
【问题描述】:
如果有人在 Google 上搜索“notify() 和 notifyAll() 之间的差异”,则会弹出很多解释(撇开 javadoc 段落)。这一切都归结为被唤醒的等待线程的数量:notify() 中的一个,notifyAll() 中的所有线程。
但是(如果我确实理解这些方法之间的区别的话),总是只选择一个线程来进一步获取监视器;在第一种情况下,由 VM 选择,在第二种情况下,由系统线程调度程序选择。程序员不知道它们的确切选择过程(在一般情况下)。
那么notify() 和notifyAll() 之间的有用 区别是什么?我错过了什么吗?
【问题讨论】:
-
用于并发的有用库在并发库中。我建议在几乎所有情况下这些都是更好的选择。 Concurency 库早于 Java 5.0(它们是在 2004 年作为标准添加的)
-
我不同意彼得的观点。并发库是用Java实现的,每次调用lock()、unlock()等都会执行很多Java代码。你可以用并发库而不是旧的
synchronized来打自己的脚,除了某些相当罕见的用例。 -
关键的误解似乎是这样的:...总是选择一个线程进行进一步的监视器采集;在第一种情况下是由 VM 选择的,在第二种情况下是由系统线程调度程序选择的。 这意味着它们本质上是相同的。虽然所描述的行为是正确的,但缺少的是在
notifyAll()的情况下,_第一个线程之后的其他线程保持清醒并将一个接一个地获取监视器。在notify的情况下,甚至没有其他线程被唤醒。所以在功能上它们是非常不同的! -
1) 如果有很多线程正在等待一个对象,并且 notify() 只在该对象上调用一次。除了等待线程之一,其余线程永远等待吗? 2) 如果使用 notify(),则只有一个等待线程开始执行。如果使用 notifyall() 通知所有等待的线程,但只有其中一个开始执行,那么这里的 notifyall() 有什么用?
-
@ChetanGowda 通知所有线程与仅通知一个任意线程实际上有显着差异,直到那个看似微妙但重要的差异引起我们的注意。当您仅 notify() 1 个线程时,所有其他线程都将在等待状态,直到它收到明确的通知/信号。通知所有人,所有线程将一个接一个地以某种顺序执行和完成,没有任何进一步的通知 - 这里我们应该说线程是
blocked而不是waiting。当blocked它的执行被暂时挂起,直到另一个线程在sync块内。
标签: java multithreading