我的印象是大多数人只使用Oracle提供的jvm实现(最初来自Sun microsystems)。如果我错了,请纠正我。
当我浏览API for notify()时,它说:
唤醒正在此对象监视器上等待的单个线程。如果 任何线程都在等待这个对象,其中一个被选中 惊醒。 选择是任意的,由酌情决定 实施。
我想知道以什么顺序在Oracle的jvm中调用notify()时将调用等待的线程。
你可能想知道我为什么不考虑使用notifyAll()而只是不用担心。但是,当我只使用notify()调用一个线程时,为什么要不必要地调用所有等待的线程?即使我使用notifyAll(),我也无法控制哪个等待线程将获得监视器。
Oracle应该在上面给出的api链接中记录它是如何在自己的实现中实现的。
答案 0 :(得分:4)
使用Threads执行的顺序未定义。
如果您根据可以预测执行顺序的假设编写任何代码,它最多只能在一台机器上运行。因此,Oracle实际实现它的方式 - 除了研究案例 - 无关紧要,因为它可能在下一台机器甚至下一版本的Oracle JVM上实现不同。
如果您需要更精细的控制,那么您需要调整架构并以正确的方式使用concurrent package中的类。同步/等待/通知只是一个非常基本的“暴力”实现线程同步,具有许多陷阱和限制。
答案 1 :(得分:2)
您只能依赖API所说的内容,并且API不保证任何特定订单。如果您需要线程以某种顺序唤醒,请在公平模式下使用ReentrantLock,然后此锁定的Condition.signal()将唤醒等待此条件最长的线程。
答案 2 :(得分:0)
您可以在构造函数中使用带有公平标记的ReentrantLock(boolean fair)
。从这种锁中创造的条件也是公平的:
使用给定的公平政策创建ReentrantLock实例。
和
从等待返回的线程的锁重新获取的顺序 方法与最初获取锁的线程相同,即 在默认情况下没有指定,但公平锁有利于那些 等待时间最长的线程。