指令重排详解
小于 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 = a | y = b |
b = 1 | a = 2 |
正常的结果:x = 0,y = 0。
线程A | 线程B |
---|---|
b = 1 | a = 2 |
x = a | y = b |
但是可能由于指令重排,导致诡异结果:x = 2,y = 1。
volatile禁止指令重排
内存屏障。CPU指令。
- 保证特定的操作的执行顺序。
- 可以保证某些变量的内存可见性。
加上volatile会在编译后的代码块前后加上内存屏障,禁止指令重排。