• 聊聊volatile作用,原理


    volatile关键字是Java虚拟机提供的的最轻量级的同步机制。它作为一个修饰符,用来修饰变量。它保证变量对所有线程可见性,禁止指令重排,但是不保证原子性。

    我们先来一起回忆下java内存模型(jmm):

    Java虚拟机规范试图定义一种Java内存模型,来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台上都能达到一致的内存访问效果。
    Java内存模型规定所有的变量都是存在主内存当中,每个线程都有自己的工作内存。这里的变量包括实例变量和静态变量,但是不包括局部变量,因为局部变量是线程私有的。
    线程的工作内存保存了被该线程使用的变量的主内存副本,线程对变量的所有操作都必须在工作内存中进行,而不能直接操作主内存。并且每个线程不能访问其他线程的工作内存。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XBTbUUjC-1661215614276)(https://a.perfma.net/img/4418586#pic_center)]
    在这里插入图片描述
    volatile变量,保证新值能立即同步回主内存,以及每次使用前立即从主内存刷新,所以我们说volatile保证了多线程操作变量的可见性。
    volatile保证可见性和禁止指令重排,都跟内存屏障有关。我们来看一段volatile使用的demo代码:

    public class Singleton {  
       private volatile static Singleton instance;  
       private Singleton (){}  
       public static Singleton getInstance() {  
       if (instance == null) {  
           synchronized (Singleton.class) {  
           if (instance == null) {  
               instance = new Singleton();  
           }  
           }  
       }  
       return instance;  
       }  
    }  
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    编译后,对比有volatile关键字和没有volatile关键字时所生成的汇编代码,发现有volatile关键字修饰时,会多出一个lock addl $0x0,(%esp),即多出一个lock前缀指令,lock指令相当于一个内存屏障
    lock指令相当于一个内存屏障,它保证以下这几点:

    重排序时不能把后面的指令重排序到内存屏障之前的位置
    将本处理器的缓存写入内存
    如果是写入动作,会导致其他处理器中对应的缓存无效。
    第2点和第3点就是保证volatile保证可见性的体现嘛,第1点就是禁止指令重排的体现。
    内存屏障四大分类:(Load 代表读取指令,Store代表写入指令)
    在这里插入图片描述
    在每个volatile写操作的前面插入一个StoreStore屏障。
    在每个volatile写操作的后面插入一个StoreLoad屏障。
    在每个volatile读操作的后面插入一个LoadLoad屏障。
    在每个volatile读操作的后面插入一个LoadStore屏障。
    有些小伙伴,可能对这个还是有点疑惑,内存屏障这玩意太抽象了。我们照着代码看下吧:
    在这里插入图片描述
    内存屏障保证前面的指令先执行,所以这就保证了禁止了指令重排啦,同时内存屏障保证缓存写入内存和其他处理器缓存失效,这也就保证了可见性

  • 相关阅读:
    MCU的环形FIFO
    springboot+高校失物招领系统 毕业设计-附源码121441
    在Mac m1运行ChatGLM3-6B cpu版本1-3秒出结果,速度明显超过T4 GPU,接近V100。
    Docker swarm 集群搭建
    Mybatis 二级缓存(使用Redis作为二级缓存)
    AWS Glue Pyspark+Athena基础学习汇总
    java计算机毕业设计盘山县智慧项目管理系统源码+系统+数据库+lw文档+mybatis+运行部署
    Kamiya丨Kamiya艾美捷小鼠高敏CRP ELISA说明书
    (214)Verilog HDL:状态机实现使能移位寄存器
    Linux:使用ssl加密网站为https
  • 原文地址:https://blog.csdn.net/weixin_44547668/article/details/126477331