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


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

    1. public class VolatileDemo {
    2. private static int flag = 0;
    3. //private volatile static int flag = 0;
    4. public static void main(String[] args) {
    5. new Thread(){
    6. @Override
    7. public void run() {
    8. int localFlag = flag;
    9. while (true){
    10. if (localFlag != flag){
    11. System.out.println("读取到被修改的flag值为:"+flag);
    12. localFlag = flag;
    13. }
    14. }
    15. }
    16. }.start();
    17. new Thread(){
    18. @Override
    19. public void run() {
    20. int localFlag = flag;
    21. while (true){
    22. System.out.println("flag被修改为了:"+ ++localFlag);
    23. flag = localFlag;
    24. try {
    25. Thread.sleep(1000);
    26. } catch (InterruptedException e) {
    27. e.printStackTrace();
    28. }
    29. }
    30. }
    31. }.start();
    32. }
    33. }

            执行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到底是如何保证可见的?对volatile修饰的变量,执行写操作的话,jvm会往CPU发送一条lock前缀的指令,CPU计算完成后会立即将这个值写回主内存。同时因为有MESI缓存一致性协议,所以各个CPU都会对总线进行嗅探,自己本地缓存中的数据是否被别人修改。如果发现别人修改了某个缓存数据,那么CPU就会将自己本地缓存中的数据过期掉,然后这个CPU上的线程再执行该缓存数据时,会从主内存加载最新的数据。

  • 相关阅读:
    vue ant 隐藏 列
    ES优化实战 - 小操作节省百分之三十以上的磁盘空间
    uni-app中返回顶部的方法
    剑指offer 44. 从1到n整数中1出现的次数
    Unity按钮无反应
    业务组件化 —— 创建、发布、使用业务组件
    【竞技宝】DOTA2-梦幻联赛S22:AR命悬一线 XG确定晋级淘汰赛
    Stable Diffusion AI绘图
    NSSCTF第12页(1)
    奥康的高尔夫鞋,圈不住投资者的心
  • 原文地址:https://blog.csdn.net/u010096526/article/details/133687284