【问题标题】:Understanding JVM Happens-before and reorder理解 JVM Happens-before 和重新排序
【发布时间】:2011-07-09 09:38:51
【问题描述】:

我正在阅读关于内存模型的 JLS 规范,17.4.5 Happens-before Order。 我不明白第一条规则:

"# 如果 x 和 y 是同一个线程的动作并且 x 在程序中在 y 之前 顺序,然后是 hb(x, y)。"

假设 A 和 B 是可以在多个线程之间共享的对象(类对象的实例):

int i=A.getNum();  // ActionA
int j=B.getNum();  // ActionB

三个问题:

  1. 按照上面的规则,是不是表示hb(ActionA,ActionB)

  2. 如果1的答案为真,是否意味着在任何遵循JSR133内存模型的JVM中,根据happens-before规则,ActionB不能重新排序到ActionA之前?

  3. 如果1和2都为真,看来ActionA和ActionB不相关,为什么不能重新排序呢?只是为了这个规范?

【问题讨论】:

    标签: java jvm


    【解决方案1】:

    据我了解:

    1. 你是对的
    2. 它们可以重新排序,但前提是操作 B 不依赖于操作 A 的结果

    Happens-before 关系没有说明重新排序操作。它只是说如果 HB(A, B) 成立,那么动作 B 必须看到动作 A 的记忆效应。

    如果动作 B 不使用动作 A 的任何结果,那么它们没有理由不能重新排序。 (一般来说,“使用其他操作的任何结果”非常广泛,只能检测到非常简单的操作,如内存读/写,而不是使用外部资源的操作,如 I/O 操作或基于时间的操作)

    【讨论】:

      【解决方案2】:

      是的,ActionA 发生在 ActionB 之前。不过,请在该部分中进一步阅读。这并不一定意味着 JVM 不能重新排序这些。也就是说ActionB必须观察ActionA的效果,仅此而已。如果 ActionB 从不依赖于 ActionA 的效果,那是很正常的。

      【讨论】:

        【解决方案3】:

        您的理解基本上是正确的。但是,要记住的关键是:

        • 如果重新排序不影响运行线程的结果,则允许重新排序
        • 意味着如果它影响其他线程,则允许重新排序不允许

        这最后一个事实是 Java 多线程编程中常见的错误和困惑来源。

        【讨论】:

          猜你喜欢
          • 2019-06-02
          • 1970-01-01
          • 1970-01-01
          • 2018-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-05
          • 1970-01-01
          相关资源
          最近更新 更多