美文网首页
volatile详解

volatile详解

作者: dashu52 | 来源:发表于2020-06-16 20:29 被阅读0次

Java内存模型

想要理解 volatile 为什么能确保可见性,就要先理解Java中的内存模型是什么 样的。 Java内存模型规定了所有的变量都存储在主内存中。每条线程中还有自己的工作内 存,线程的工作内存中保存了被该线程所使用到的变量(这些变量是从主内存中拷 贝而来)。线程对变量的所有操作(读取,赋值)都必须在工作内存中进行。不同 线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过 主内存来完成。


image.png

volatile的实现原理

  1. 可见性
    处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内 部缓存后再进行操作,但操作完后不知什么时候会写到内存。 如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指 令,将这个变量所在缓存行的数据写会到系统内存。 这一步确保了如果有其他线程 对声明了volatile变量进行修改,则立即更新主内存中数据。但这时候其他处理器的缓存还是旧的,所以在多处理器环境下,为了保证各个处理 器缓存一致,每个处理会通过嗅探在总线上传播的数据来检查 自己的缓存是否过 期, 当处理器发现自己缓存行对应的内存地址被修改了,就会将当前处理器的缓存 行设置成无效状态,当处理器要对这个数据进行修改操作时,会强制重新从系统内 存把数据读到处理器缓存里。 这一步确保了其他线程获得的声明了volatile变量都是 从主内存中获取最新的。

2.有序性
Lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),它确保指令重排序时 不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障 的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成。

volatile应用场景

  • volatile 修饰单例模式里面的instance
class Singleton {
 private volatile static Singleton instance = null;
 private Singleton() { }
public static Singleton getInstance() { 
if (instance == null) { 
synchronized (Singleton.class) { 
   if (instance == null) 
      instance = new Singleton();
   } 
}
return instance;
} 
}
  • 为什么要使用volatile 修饰instance?
    主要在于instance = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情:
  1. 给 instance 分配内存
  2. 调用 Singleton 的构造函数来初始化成员变量
  3. 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)。

但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第 三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是 后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺 理成章地报错。

相关文章

  • volatile、synchronized、lock详解

    volatile、synchronized、lock详解 1、volatile 被volatile定义的变量被一个...

  • volatile详解(二)(重排序)

    volatile保证线程安全可见性——volatile详解(一)[https://www.jianshu.com/...

  • volatile详解

    今天来介绍一下volatitle volatile是什么 volatitle是一个确保共享变量能够被准确和一致地更...

  • volatile详解

    volatile可以说是最轻量级的同步工具,但是要使用volatile来保证业务的安全和一致性,我们需要对其...

  • volatile详解

    Java内存模型 想要理解 volatile 为什么能确保可见性,就要先理解Java中的内存模型是什么 样的。 J...

  • volatile详解

    一、volatile简介 在单线程环境中,我们几乎用不到这个关键词,但是多线程环境中,这个关键词随处可见。而且也是...

  • volatile详解

    对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好...

  • Java中的锁

    锁产生的背景 volatile和synchronized Lock接口 ReenTrantLock使用详解 同步实...

  • c++ volatile关键字

    Ref cppreference - const vs volatileC/C++中volatile关键字详解 v...

  • 并发编程系列-volatile详解

    并发编程系列-volatile详解 前言 面试过程中,常见的双层校验锁会引发出去使用volatile关键字这个问题...

网友评论

      本文标题:volatile详解

      本文链接:https://www.haomeiwen.com/subject/fitdxktx.html