作者:蓝天ab白云 | 来源:互联网 | 2023-06-24 16:25
volatile关键字试图阻止过度优化,volatile基本可以做到两件事情:1.阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。2.阻止编译器调整操作volatile变量
volatile关键字试图阻止过度优化,volatile基本可以做到两件事情:
1. 阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。
2. 阻止编译器调整操作 volatile变量的指令顺序。
为什么要这么做,这么做有什么目的?
我们先看2个例子,也是有关多线程安全的
例1:
x = 0
Thread1 Thread2
lock(); lock();
x++; x++;
unlock(); unlock()'
表面上看,因为有lock的保护,x的最终结果应该是2,这也是大部分执行的场景下的结果。但是,深入挖掘这个过程,其实并没有那么理想。编译器为了提高速度,把x放到某个寄存器里,执行完x++后,有时候暂时不更新寄存器。导致结果可能为1.
例2:
x = y = 0;
Thread1 Thread2
x = 1; y = 1;
r1 = y; r2 = x
表面上看,r1 和 r2至少应该有一个为1,实际上r1 = r2 = 0的情况,会有发生。在执行程序的时候,由于cpu动态调度,为了提高效率有可能会交换指令顺序。同样,编译器在优化时候,也可能为了效率而交换毫不相干的两条相邻指令。
导致执行时,
x = y = 0;
Thread1 Thread2
r1 = y; y = 1;
x = 1; r2 = x
注:volatile 可以完美解决例1的问题,但是volatile不能完全解决例2问题,只能阻止编译器调整顺序,无法阻止cpu动态调度换序。