volatile关键字 初探

volatile关键字试图阻止过度优化,volatile基本可以做到两件事情:

1. 阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。

2. 阻止编译器调整操作 volatile变量的指令顺序。

 

为什么要这么做,这么做有什么目的?

我们先看2个例子,也是有关多线程安全的

例1:

x = 0

Thread1          Thread2

lock();               lock();

x++;                  x++;

unlock();            unlock()'

表面上看,因为有lock的保护,x的最终结果应该是2,这也是大部分执行的场景下的结果。但是,深入挖掘这个过程,其实并没有那么理想。编译器为了提高速度,把x放到某个寄存器里,执行完x++后,有时候暂时不更新寄存器。导致结果可能为1.

volatile关键字 初探

例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动态调度换序。