指令重排详解

HeJin小于 1 分钟JavaJUC并发编程

指令重排


写的程序,计算机并不是按照你写的那样去执行的。


源代码 -> 编译器优化的重排 -> 指令并行也可能重排 -> 内存系统也会重排

int x = 1;  // 1
int y = 2;  // 2
x = x + 5;  // 3
y = x * x;  // 4
我们所期望的:1 2 3 4
2 1 3 4 程序也能跑
1 3 2 4 程序也能跑
可不可能是4 1 2 3

处理器在进行指令重排的时候,会考虑数据之间的依赖性


可能造成影响的结果:a、b、x、y默认都是0

线程A线程B
x = ay = b
b = 1a = 2

正常的结果:x = 0,y = 0。

线程A线程B
b = 1a = 2
x = ay = b

但是可能由于指令重排,导致诡异结果:x = 2,y = 1。

volatile禁止指令重排

内存屏障。CPU指令。

  • 保证特定的操作的执行顺序。
  • 可以保证某些变量的内存可见性。

加上volatile会在编译后的代码块前后加上内存屏障,禁止指令重排。