在 Java volatile Happens-Before Guarantee 部分的this tutorial中,有一个关于先发条件规则的句子:
JVM无法重新排序volatile变量的读写指令(只要JVM检测到重新排序的程序行为没有变化,JVM可能会出于性能原因重新排序指令)。
我的问题是JVM如何检测指令的重新排序。我们是否可以在任何地方编写任何示例,规范或注释,以便在重新排序指令时更好地理解JVM性能?我在网上找不到任何有用的东西。
答案 0 :(得分:1)
可以重新排序指令以确保管道不会停止。假设您有一系列指令,并且每条指令在某种程度上取决于前一条指令。然后处理器不能并行执行这些指令,因为每条指令的执行阶段(有时甚至是解码阶段)(从获取,解码,执行和存储)循环将取决于前一条指令的执行阶段,因此气泡或nop (无操作)需要引入。
为了防止这种情况,JVM或硬件可以重新排序指令,使得对先前指令的依赖性不会通过在其间执行一些其他非依赖性指令而使流水线停顿。在这样做时,JVM或硬件的工作是确保重新排序指令不会以任何方式改变程序按顺序执行的行为。
volatile关键字保证在读取写入volatile变量的值的任何线程都可以看到在volatile写入之前写入(可以是非易失性的)变量的状态。这就像同步一样,尽管形式较弱。换句话说,使用volatile可以保证在写入volatile变量之前写入的任何内存都不会在写入volatile变量之后重新排序。同样,在从volatile变量读取之前,保证不会重新排序任何对变量的读取。
JVM可以通过添加fence指令来阻止指令重新排序,该指令阻止对围栏周围的指令进行优化。