Oracle的JVM中notify()实现

3
我认为大多数人只使用Oracle提供的jvm实现(最初来自Sun Microsystems)。如果我错了,请纠正我。
当我阅读notify() API时,它说:
唤醒等待此对象监视器的单个线程。如果有任何线程在等待此对象,则选择其中一个线程被唤醒。选择是任意的,并由实现自行决定。
我想知道在Oracle的jvm中调用notify()时等待线程将以什么顺序被调用。
你可能会想为什么我不考虑使用notifyAll()并停止担心。但是,当我可以使用notify()仅调用一个线程时,为什么应该不必要地调用所有等待的线程呢?即使我使用notifyAll(),我也无法控制哪个等待的线程将获取监视器。
Oracle应该在上面给出的API链接中记录其自己的实现方式。

2
如果您需要通知特定的线程,您应该考虑为此情况使用另一个监视器。 - Taky
https://dev59.com/_2gv5IYBdhLWcg3wVPPU?rq=1 是一个关于该主题的好问题。 - Danstahr
3个回答

4

线程的执行顺序是不确定的。

如果您编写基于可以预测执行顺序这一假设的代码,那么它最多只能在单台计算机上运行。因此,Oracle实际实现它的方式 - 除了研究案例外 - 是无关紧要的,因为它可能在下一台机器上甚至在Oracle JVM的下一个版本中以不同的方式实现。

如果您需要更细粒度的控制,则需要调整您的架构并正确使用并发包中的类。Synchronized/wait/notify只是使用许多陷阱和限制的基本线程同步的“蛮力”实现。


2

您只能依赖API所说的,API并不保证任何特定顺序。如果您需要线程按照特定顺序唤醒,请使用公平模式下的ReentrantLock,然后该锁的Condition.signal()方法将唤醒等待时间最长的线程。


0

你可以在构造函数中使用带有公平性标志的 ReentrantLock(boolean fair)。从此类锁创建的条件也是公平的:

使用给定的公平策略创建 ReentrantLock 的实例。

而且

从等待方法返回的线程重新获取锁的顺序与最初获取锁的线程相同,在默认情况下未指定,但对于公平锁,它会优先考虑那些等待时间最长的线程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接