volatile如何保证可见性和防止重排序

1 保证可见性:

内存可见性是指一个CPU对数据修改,此修改对其他CPU立即可见。

(1)"CPU对数据修改":

CPU对数据的修改总是先修改工作内存,然后再同步回主内存,只不过对被volatile修饰的变量的修改,会立刻同步回主内存。

(2)"此修改对其他CPU立即可见":

当CPU_A修改完volatile变量,并且立即同步回主存,如果CPU_B的工作内存中也缓存了这个变量,那么CPU_B的这个变量将立即失效,当CPU_B想要修改这个变量的时候,CPU_B必须从主存中重新获取该变量的值。

实现原理:

基于CPU的MESI协议(缓存一致性协议),其中M表示Modify,E表示独占Exclusive,S表示Shared,I表示Invalid。如果一个CPU修改了数据,那么这个CPU的数据状态就会更新成M,同时其他CPU上的数据状态更新成I,这个是通过CPU多核之间的嗅探机制实现的。

2 防止重排序:

实现原理:

内存屏障(Memory Barrier),像一套栅栏分割前后的代码,阻止栅栏前后的没有数据依赖性的代码进行指令重排序,保证程序在一定程度上的有序性。

在单例模式中,Instance inst = new Instance();   这一句代码不是原子操作,它可以分成三步原子指令:

(1)分配内存地址;

(2)new一个Instance对象;

(3)将内存地址赋值给inst;

CPU为了提高执行效率,这三步操作的顺序可以是123,也可以是132。如果是132顺序的话,当把内存地址赋给inst后,inst指向的内存地址上面还没有new出来单例对象,这时候,如果就拿到inst的话,它其实就是空的,会报空指针异常。

这就是为什么双重检查单例模式中,单例对象要加上volatile关键字。双重检查单例模式,单例对象为何要加上volatile关键字?_vimer-hz的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值