Volatile 的底层原理及实现方式

 观察加入Volatile 关键字和没有加入volatile 关键字产生的汇编代码发现:加入volatile 关键字,会多出来一个lock前缀指令。查阅资料:lock前缀指令实际上相当于一个内存屏障(亦称内存栅栏),内存屏障会提供3个功能:

1、它确保指令重排序时,不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障指令时,前面的操作已经全部完成。

2、他会强制将对缓存的修改操作立即写入主存

3、如果是写操作,他会导致其他CPU中对应的缓存行无效。

 

第一点实现了 volatile 禁止指令重排序,有序性

指令重排序:编译器和处理器未来提高程序的执行效率,在不违背happens-before规则的前提下针对程序的执行顺序进行重新排序的处理。

volatile 的禁止指令重排序:1、当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经完成,且结果已经对后面的操作可见;在其后面的操作肯定还没有开始;2、在进行指令优化时,不能将在 volatile 变量前面的语句放在其后面执行,也不能把volatile 变量后面的语句放到其前面执行。

为什么要禁止指令重排序? 

指令的重排序可能会造成 空指针等异常。比如在一个成员变量未初始化的时候,提前使用了他。

 

 

第二、三点实现了线程间的可见性

如果一个变量被volatile 所修饰的话,在每次数据变化之后,其值都会被立刻强制刷入主存,而其他处理器的缓存由于遵守了缓存一致性协议,也会把这个变量的值从主存加载到自己的缓存中【在使用这个数据前】

已经有了缓存一致性协议,为啥还需要Volatile 关键字?  ------ 答案来源于网络

1、不是所有的硬件架构都提供了相同的一致性保证,Java 作为一门夸平台语言,JVM需要提供一个统一的语义。

2、操作系统中的缓存和JVM中线程的本地内存并不是同一回事。MESI可以解决缓存层面的可见性问题,Volatile 可以解决JVM层面的可见性问题

3、缓存一致性模型只能保证缓存变更其他缓存也跟着改变,但是不能保证立刻执行。原因:由于传统的MESI协议的执行成本比较大,所以CPU通过Store Buffer 和Invalidate Queue组件来解决,但是由于这2个组件的引入,导致 缓存与主存之间的交互不是实时进行的

 

 

 补充知识:

CPU缓存:

由于主存的读取写速度远远跟不上CPU的处理速度,严重影响其效率,所以才有了CPU缓存,作为主存和CPU之间的缓冲区,就是提前把CPU处理需要用到的数据加载到CPU缓存中,CPU从CPU缓存中读取数据进行处理,之后将处理结果存到对应的CPU缓存中,最后由CPU缓存刷新到主存中 。(缓存分为3级:L1,L2,L3  :在 L1中找不到,再从L2中查找,L2中找不到,就从L3中查找,L3中找不到,再从主内存中读取)

 

在单核处理器的情况下,没有任何问题。但是出现了多核处理器的时,CPU缓存会存在多个,彼此是独立的。由此会产生一个问题:多个CPU缓存读取了同一个变量,然后都进行了修改,那么最后写入到内存的数据肯定是错误的。

由此大佬们制定了 CPU的缓存一致性协议【MESI】,如下:

MESI协议将CPU缓存的状态分为【M】modify、【E】exclusive、【S】shared、【I】invalid分别是修改、独占、共享、失效。

  1. Modified状态:当前缓存中的内容与内存不同,是脏的(dirty),并且只有一个core拥有这个cache block的副本
  2. Exclusive状态:当前缓存中的内容与内存一致,是干净的(clean),并且只有一个core拥有这个cache block的副本
  3. Shared状态:当前缓存中的内容与内存一致,是干净的(clean),但是不止一个core拥有这个cache block的副本
  4. Invalid状态:当前缓存中的内容过时(无效)

具体变化,百度搜索:MESI状态迁移

协议主要内容是:每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作时,会强制重新从系统内存里把数据读到处理器缓存里

嗅探:所有主存的传输都发生在一条共享的总线上,而所有的处理器都能看到这条总线,缓存本身是独立的,但是内存是共享资源,所有的主存访问都要经过仲裁【同一个指令周期,只有一个CPU缓存可以读写内存】;CPU缓存同时还在不停的嗅探总线上发生的数据交换。所以当其中一个CPU缓存去读写主存时,其他CPU都会得到通知,以此来更新自己的缓存状态,保持数据的同步。

计算机上面的数据,是存放在主存当中的,也就是计算机的物理内存

如有问题请指出!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值