当前位置: 首页 > news >正文

手写Demo体验volatile可见性的作用

        volatile是java的关键字,作用:①保证线程间的可见性;②防止指令重排。下面看一个demo,启动2个线程,一个线程读取flag变量的值,另外一个线程修改flag变量的值。

public class VolatileDemo {
    private static int flag = 0;
    //private volatile static int flag = 0;

    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                int localFlag = flag;
                while (true){
                    if (localFlag != flag){
                        System.out.println("读取到被修改的flag值为:"+flag);
                        localFlag = flag;
                    }
                }
            }
        }.start();
        
        new Thread(){
            @Override
            public void run() {
                int localFlag = flag;
                while (true){
                    System.out.println("flag被修改为了:"+ ++localFlag);
                    flag = localFlag;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                
            }
        }.start();
    }
}

        执行2遍,区别是否有volatile的修饰,执行结果如下。

        为什么使用volatile关键字,就能保证线程之间变量的可见性?它是如何做到的?如下图是该例的java内存模型。其实java内存模型的实现,是参考了CPU缓存模型。CPU缓存不一致的问题,早期是用总线加锁机制来实现,但是效率太差,很容易出现串行化的问题。

        后来常用MESI协议:MESI(Modified Exclusive Share Invalid)(也称伊利诺斯协议)是一种广泛使用的支持写回策略的缓存一致性协议,该协议被应用在 Intel 奔腾系列的 CPU 中。当一个 CPU 修改了 高速缓存中的数据,会通知其他缓存了这个数据的 CPU,其他 CPU 会把 自己高速缓存 中这份数据置为无效,要读取数据的话,直接去内存中获取,不会再从缓存中获取了。

        如下图java内存模型:线程的工作内存和主内存,read(从主存读取),load(将主存读取到的值写入工作内存),use(从工作内存读取数据来计算),assign(将计算好的值重新赋值到工作内存中),store(将工作内存数据写入主存),write(将store过去的变量值赋值给主存中的变量)。

        那volatile到底是如何保证可见的?结合上图的java内存模型,如果该变量是volatile修饰的,那assign操作后,一定会强制保证立马执行store + write,刷回到主内存里去。同时会让其他线程工作内存里的flag变量过期,从主内存重新读取。

相关文章:

  • 计算机网络-计算机网络体系结构-物理层
  • 深度学习笔记之优化算法(三)动量法的简单认识
  • 设计模式之代理模式
  • 【运维笔记】Centos 7.5 安装 Docker详细步骤
  • 光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码)
  • uniapp echarts 适配H5与微信小程序
  • 传统机器学习聚类算法——总集篇
  • kafka简易搭建(windows环境)
  • 使用postman 调用 Webservice 接口
  • Vue中如何进行数据可视化雷达图展示
  • 八大排序java
  • 阿里测试师用UI自动化测试实现元素定位!
  • 微服务技术栈-Gateway服务网关
  • Git 学习笔记 | Git 基本理论
  • H5+Css3文本溢出添加省略号(包括插件)
  • 【用unity实现100个游戏之14】Unity2d做一个建造与防御类rts游戏
  • 这7个AI软件让设计效率飞起,快来收藏 优漫动游
  • windows C 开发
  • freertos信号量之二值信号量
  • C++ - 右值引用 和 移动拷贝
  • 英国首相斯塔默住所起火,警方紧急调查情况
  • 60余年产业积累,“江苏绿心”金湖炼就“超级石油工具箱”
  • 甩掉“肥胖刺客”,科学减重指南来了
  • 上海与世界|环城生态公园带是上海绿色发展新名片
  • 人民日报:浙江着力提升民营企业核心竞争力
  • 普京提议重启俄乌直接谈判后,特朗普表态了