多线程之volatile原理分析
volatile与有序性
volatile一个强大的功能,那就是他可以禁止指令重排优化。通过禁止指令重排优化,就可以保证代码程序会严格按照代码的先后顺序执行。那么volatile又是如何禁止指令重排的呢?
先给出结论:volatile是通过内存屏障来来禁止指令重排的。
**内存屏障(Memory Barrier)**是一类同步屏障指令,是CPU或编译器在对内存随机访问的操作中的一个同步点,使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作。
volatile通过在volatile变量的操作前后插入内存屏障的方式,来禁止指令重排,进而保证多线程情况下对共享变量的有序性。
volatile与可见性
Java中的volatile
关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。
其实,volatile对于可见性的实现,内存屏障也起着至关重要的作用。因为内存屏障相当于一个数据同步点,他要保证在这个同步点之后的读写操作必须在这个点之前的读写操作都执行完之后才可以执行。并且在遇到内存屏障的时候,缓存数据会和主存进行同步,或者把缓存数据写入主存、或者从主存把数据读取到缓存。
volatile与原子性
volatile
是不能保证原子性的。
总结:
1、用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。
2、volatile和原子性、有序性以及可见性之间的关系。有序性和可见性是通过内存屏障实现的。而volatile是无法保证原子性的。