深度剖析Java的volatile实现原理,再也不怕面试官问了( 三 )


内存屏障有两个作用:一是保证特定操作的执行顺序,二是保证某些变量的内存可见性 。
volatile内存语义的实现: JMM 针对编译器制定的 volatile 重排序规则表
操作普通读写volatile读volatile写普通读写可以重排可以重排不可以重排volatile读不可以重排不可以重排不可以重排volatile写可以重排不可以重排不可以重排编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序:

  • 在每个volatile写操作的前面插入一个StoreStore屏障
  • 在每个volatile写操作的后面插入一个StoreLoad屏障
  • 在每个volatile读操作的后面插入一个LoadLoad屏障
  • 在每个volatile读操作的后面插入一个LoadStore屏障
6. volatile应用场景volatile可以保证可见性和有序性,但无法保证原子性 。所以它的应用场景就不如synchronized广泛,主要有两个场景:一是做状态变量,二是做需要重新赋值的共享对象 。
比如:第二种场景常见的就有修饰单例模式的对象 。
public class Singleton {// 使用volatile修饰,赋值后,其他线程能立即感知到private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}还有就是CopyOnWriteArrayList的底层实现就是用volatile修饰的数组,因为CopyOnWriteArrayList每次修改数据后都会数组重新赋值,而不是只修改数据中的一个值,这样才能保证了CopyOnWriteArrayList的数据安全性 。
深度剖析Java的volatile实现原理,再也不怕面试官问了

文章插图
我是「一灯架构」,如果本文对你有帮助,欢迎各位小伙伴点赞、评论和关注,感谢各位老铁,我们下期见

深度剖析Java的volatile实现原理,再也不怕面试官问了

文章插图

经验总结扩展阅读