【问题标题】:notify() implementation in Oracle's jvm在 Oracle 的 jvm 中实现 notify()
【发布时间】:2013-12-04 13:01:34
【问题描述】:

我的印象是大多数人只使用 Oracle 提供的 jvm 实现(最初来自 Sun 微系统)。如果我错了,请纠正我。

当我通过API for notify() 时,它说:

唤醒在此对象的监视器上等待的单个线程。如果 任何线程都在等待这个对象,其中一个被选为 醒来。 选择是任意的,由以下人员自行决定 实施。

我想知道在 Oracle 的 jvm 中调用 notify() 时会以什么顺序调用等待线程。

您可能想知道为什么我不考虑使用 notifyAll() 并停止担心。但是当我可以用 notify() 只调用一个线程时,我为什么要不必要地调用所有等待的线程呢?即使我使用 notifyAll(),我也无法控制哪个等待线程将获得监视器。

Oracle 应该已经在上面给出的 api 链接中记录了它是如何在自己的实现中实现的。

【问题讨论】:

标签: java multithreading jvm implementation notify


【解决方案1】:

线程的执行顺序未定义。

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

如果您需要更细粒度的控制,那么您需要调整您的架构并以适当的方式使用concurrent package 中的类。同步/等待/通知只是线程同步的一个非常基本的“蛮力”实现,有很多陷阱和限制。

【讨论】:

    【解决方案2】:

    您只能依赖 API 所说的内容,API 不保证任何特定顺序。如果您需要线程以特定顺序唤醒,请在公平模式下使用 ReentrantLock,则此锁的 Condition.signal() 将唤醒等待此 Condition 最长的线程。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-15
        • 1970-01-01
        • 2011-07-31
        • 2011-09-23
        • 2014-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多