Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java内存模型中外部操作的重新排序_Java_Concurrency_Memory Model_Java Memory Model - Fatal编程技术网

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

Java内存模型中外部操作的重新排序,java,concurrency,memory-model,java-memory-model,Java,Concurrency,Memory Model,Java Memory Model,我目前正在学习Java内存模型,以及它如何影响编译器可能进行的重新排序。然而,我对外部操作有点困惑。JMM将它们定义为一种可以在on操作之外观察到的操作。我理解外部行为是指打印值、写入文件、网络操作等 现在,外部操作如何受到重新排序的影响?我认为很明显,一个外部操作不能与另一个外部操作重新排序,因为这将改变程序的可观察行为(因此根据JMM,这不是有效的转换)。但是,如何使用正常内存访问或同步操作重新排序外部操作呢?例如: volatile int v = 5; int x = v; System

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

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

volatile int v = 5;
int x = v;
System.out.println("!");
打印和
int x=v
是否可以在此处重新排序?我看不出它在改变行为,但volatile v的读取与监视器采集相同,因此我认为重新排序是无效的。

添加了外部操作以避免意外结果:

class ExternalAction { 

  int foo = 0; 

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

  native void jni(); /* { 
    assert foo == 0; 
  } */ 
}
假设JNI方法是为了运行相同的断言而实现的,您不会期望它失败。JIT编译器无法确定任何外部操作的结果,因此JMM也禁止此类重新排序。

我的理解(可能有缺陷)是,在受保护的操作方面没有优先级。因此,volatile读取和外部写入都不能重新排序,因此您的3行示例保持不变。您可以通过将它粘贴到方法中并调用它几(十万?)次来测试它,同时使用-server和-XX:+printcomployment并比较JIT结果。