voliate底层原理分析
- volatile的作用
- 硬件层面分析
- 软件层面
- volatile分析
volatile的作用
volatile的作用是保证被它修饰的共享变量具有可见性和有序性。
什么是内存可见性/strong>
在多线程下一个线程修改了共享变量,能够立即让其他线程知道这个新值。
什么是有序性/strong>
程序在执行时会以到达更高执行效率为目的,在保证最终程序结果正确的前提下进行指令重排,有序性就是阻止指令重排,保证指令按序执行。
硬件层面分析
我们先了解下硬件层面实现防止指令重排和内存可见性的原理。
CPU缓存的出现
计算机在执行程序指令时涉及到数据的读写,而程序运行时需要的临时数据都存在主存中,这样会导致一个问题,cpu执行的速度非常快而内存读写数据的速度较慢,这样就会导致指令处理效率低下。
为了解决这个问题cpu缓存出现了(cache memory),cpu缓存读取速度快,当程序运行时将需要的数据拷贝一份到cpu缓存,cpu直接与缓存交互,程序结束后再将缓存内的结果刷回到主存,保证了cpu执行效率。
现在的的cpu基本都是采用的三级缓存,如下图:
一级二级缓存是核心独享,三级缓存是核心共享。
存储缓存和存储转发
通过上面的解决方案已经实现了cpu执行指令速度的提升以及缓存一致,但是缓存一致性协议是基于四个状态的切换(Modified、Exclusive、Share、Invalid),这就需要各个CPU之间进行交互(一个cpu改变共享变量通知其他cpu缓存中的该变量失效,然后等到失效成功消息回复给它在继续执行指令,在等待过程中就会造成cpu的阻塞——相当于同步处理),在这个过程中也会导致时延降低cpu的处理效率。
所以存储缓存和存储转发就出现了,
存储缓存(Store Buffer)是让上面的同步处理变为异步处理,它是在cpu和cpu缓存之间,思想就是让cpu把要写入缓存的数据先写入store buffer中,然后它就可以去执行其他指令,当接收其他cpu的回复消息时再把存储缓存中的数据写入缓存,然后在清除掉存储缓存中数据,这样就可以使cpu不用阻塞。
存储转发(Store Forward)是当cpu需要数据时先查看存储缓存中有无数据,如果有直接在里面读取,如果没有则去缓存中读取,这样做可以解决这样的问题:当一个cpu写入数据到存储缓存,但是存储缓存还没有写入缓存时,cpu再次用到这个数据读取的是缓存中的旧值导致错误。
还有什么地方需要优化吗/strong>
当然有,我们可以想象当其他cpu接受到失效指令(某个cpu0发送的让共享变量失效),但是此时其他的cpu在处理某些指令不能立即发送回复失效指令回去,那这个失效指令就陷入等待,并且存储缓存又很小,长时间接受不到其他cpu回复很可能就满了。要解决这个问题就要引入“失效队列”
失效队列的思想:让失效指令进入到失效队列,然后其他cpu知道失效队列中有这个失效指令就可以发送回复消息给cpu0,不用让失效指令陷入阻塞。
CPU内存屏障
因为CPU指令重排导致的问题引入内存屏障解决
写屏障(store memory barrier):看到写屏障就是要求写屏障前面的所有写指令执行完毕才能继续执行,保证写入最新数据。
读屏障(load memory barrier):读屏障之后的读操作都要在读屏障之后执行,保证读取到最新的数据。
全屏障(full memory barrier):兼备读写屏障的功能。
内存屏障防止cpu乱序执行(指令重排)带来问题。
以上就是硬件层面实现内存可见性以及防止指令重排。
软件层面
下面我们来分析软件层面怎么实现可见性和有序性
在JAVA中实现了java内存模型(JMM),它将硬件层面的的问题进行了抽象,屏蔽了不同平台硬件之间的差异,通过实现了JMM层面的内存屏障解决指令重排问题,通过将内存分为主内存和线程工作内存按照一定规则控制交互实现内存可见性。
主内存所有线程共享,工作内存每个线程独享。工作内存中有一份主内存共享变量的副本。
为了实现这个语义,JVM在生成字节码时,会在指令序列中插入内存屏障(memory barrier)来禁止特定类型的处理器指令重排,对于编译器来讲对全部的CPU来插入屏障数最小的方案几乎不可能,下面是基于保守策略的JMM内存屏障插入策略:
1.在每个volatile写操作的前面插入一个StoreStore屏障
2.在每个volatile写操作的后面插入一个SotreLoad屏障
3.在每个volatile读操作的后面插入一个LoadLoad屏障
4.在每个volatile读操作的后面插入一个LoadStore屏障
如有错误欢迎指正,共同进步。
下篇文章分析重排表的规则!!!
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91536 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!