理解JVM之前发生并重新排序

时间:2011-07-09 09:38:51

标签: java jvm

我正在阅读关于内存模型的{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的答案为真,那么根据发生前的规则是否意味着ActionB不能在任何遵循JSR133内存模型的JVM中重新排序到ActionA之前?

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

3 个答案:

答案 0 :(得分:9)

我的理解是:

  1. 你是对的
  2. 它们可以重新排序,但仅当行动B不依赖于行动结果A
  3. 发生之前 - 之前的关系没有说明重新排序行动。它只表示如果HB(A,B)成立,那么动作B必须看到动作A的记忆效应。

    如果操作B不使用任何操作A的结果,则没有理由不能重新排序。 (通常,“使用其他操作的任何结果”非常广泛,只能通过内存读/写等非常简单的操作检测,而不能检测使用外部资源(如I / O操作)或基于时间的操作的操作)

答案 1 :(得分:3)

是的,ActionA发生在ActionB之前。请仔细阅读该部分。它并不一定意味着JVM无法对这些进行重新排序。这意味着ActionB必须遵守ActionA的效果,即所有。如果ActionB从不依赖于ActionA的影响,那就简单了。

答案 2 :(得分:2)

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

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

这是最后一个事实,它是java中多线程编程中常见的错误和困惑的根源。