在Java内存模型中重新排序外部操作

时间:2015-09-22 12:34:27

标签: java concurrency memory-model java-memory-model

我目前正在学习Java内存模型,以及它如何影响编译器可能进行的重新排序。但是,我对外部操作有点困惑。 JMM将它们定义为在操作之外可以观察到的动作。离开this question,我理解外部操作就像打印一个值,写入文件,网络操作等等。

现在,外部行动如何受到重新排序的影响?我认为很明显外部动作不能与另一个外部动作重新排序,因为这会改变程序的可观察行为(因此根据JMM不是有效的转换)。但是,如果使用正常的内存访问或同步操作重新排序外部操作呢?例如:

volatile int v = 5;
int x = v;
System.out.println("!");

可以在此打印并int x = v重新排序吗?我看不到它改变行为,但是volatile v的读取与监视器获取相同,所以我不认为重新排序是有效的。

1 个答案:

答案 0 :(得分:1)

添加

外部操作以避免出现意外结果:

class ExternalAction { 

  int foo = 0; 

  void method() { 
    jni(); 
    foo = 42; 
  } 

  native void jni(); /* { 
    assert foo == 0; 
  } */ 
}

假设实现了JNI方法以运行相同的断言,您不会期望这会失败。 JIT编译器无法确定任何外部的结果,因此JMM也禁止这样的重新排序。