不算深入的理解volatile

本文参考哔哩哔哩马士兵老师课程以及网络资源所学,仅供学习使用,如若侵权,请联系

1、先从整体上说,volatile的作用

    (1)保证内存可见性

              volatile修饰的变量,线程之间使用的时候都是需要到主内存中重新获取的

    (2)防止指令重排序[CPU的乱序执行]

             假设两条指令之间没有关系的,cpu执行的时候可能会颠倒顺序(as if serivl),但是最终结果是一致的【为了提高效率】

2、验证一下Java会乱序执行

      如果指令是顺序执行的话, 以下代码是绝对不可能得到x=0,y=0的,但是当循环到一定次数,确实得到了x=0,y=0,所以指令是可以重排序的,也就是可以乱序执行的

        

3、volatile是如何禁止指令重排的呢?【这是JVM规定】

      JVM层面实现了内存屏障,也就是两条指令之间加了“一堵墙”,两个指令不允许乱移动【JVM层面的规范实现】。

      JVM中只有四种内存屏障,写store、读Load两者之间排列组合

      StoreStore、LoadLoad、StoreLoad、LoadStore

      对volatile修改的变量,是读、写之前都要加内存屏障,达到禁止指令重排。

5、虚拟机禁止指令重排底层实现 

     是通过 lock addl 指令实现的。【通知缓存行失效,也就是可见性】

     LOCK是用于多处理器中执行指令时对共享内存的独占使用。它的作用是能够将当前处理器对应的缓存的内容刷新到内存,并使其它处理器对应的缓存失效,另外还提供了有序的指令无法越过这个内存屏障的作用

5、延伸阅读

    5.1 happens-before,就是针对8种情况,不允许指令重排,也就是说必须加屏障

    5.2 as-if-serial:不管如何重排序,单线程执行结果不会改变

    5.3 缓存如何失效的?

    5.4 验证是块读取

代码改版后:

6、说一个面试题

6.1 对象的创建过程:是先申请堆内存[成员变量为默认值]--然后调用构造方法给成员变量赋值---然后建立连接

​6.2 DCL(Double Check Lock) 单例【也就是双重检查+synchronized】有没有必要加volatile修饰变量?

     答案是肯定有必要

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值