volatile底层原理

**

volatile底层原理

**
cpu的运算速度是很快的,要比内存和I/O操作快更多了,但是cpu通常是要使用内存或I/O设备中的数据进行运算的,为了最大化利用CPU的运算速度,屏蔽内存或I/O的性能短板,为CPU进行了三种优化:
1 为CPU增加了高速缓存
2 引入了线程和进程的概率,通过切换CPU的时间片,尽可能更多的利用CPU的性能
3 CPU指令优化,也就是指令重排序

**

CPU的高速缓存

**
在CPU读取内存数据时,会阻塞等待内存将数据返回,为了避免CPU资源被浪费,CPU引入了高速缓存,将内存中的数据缓存到CPU高速缓存中,CPU在更新数据时,会先更新CPU高速缓存,再更新主内存,CPU高速缓存分为L1/L2/L3,其中L1和L2是CPU私有的,L3是各CPU共享的

**

CPU解决缓存一致性问题

**
总线锁,CPU要从主内存获取数据时是需要基于总线去通讯的,当一个CPU对某个数据进行更新时,锁住总线,不允许其他CPU对此数据进行操作,即阻塞其他CPU,会带来性能问题
缓存锁,相比总线锁,实际上是缩小锁的粒度,只在多个CPU共享的缓存层面,锁住正在操作的缓存数据,通过MESI缓存一致性协议实现

**

什么是MESI?

**
是缓存行的四种状态E(exclusive)、M(modified)、S(shared)、I(invalid)。
M:代表该缓存行中的内容被修改了,并且该缓存行只被缓存在该CPU中。这个状态的缓存行中的数据和内存中的不一样,在未来的某个时刻它会被写入到内存中(当其他CPU要读取该缓存行的内容时。或者其他CPU要修改该缓存对应的内存中的内容时(个人理解CPU要修改该内存时先要读取到缓存中再进行修改),这样的话和读取缓存中的内容其实是一个道理)。

E:E代表该缓存行对应内存中的内容只被该CPU缓存,其他CPU没有缓存该缓存对应内存行中的内容。这个状态的缓存行中的内容和内存中的内容一致。该缓存可以在任何其他CPU读取该缓存对应内存中的内容时变成S状态。或者本地处理器写该缓存就会变成M状态。

S:该状态意味着数据不止存在本地CPU缓存中,还存在别的CPU的缓存中。这个状态的数据和内存中的数据是一致的。当有一个CPU修改该缓存行对应的内存的内容时会使该缓存行变成 I 状态。

I:代表该缓存行中的内容时无效的。

**

MESI协议带来的问题?

**
当某个CPU更新了共享类存时,当要把其他CPU共享的缓存置为失效时,需要阻塞等待其他CPU置为失效后的应答,为了避免这种阻塞,每个CPU引入了storebuffer存储缓冲,CPU在更新共享内存的指令放入到自己的storebuffer,然后继续执行之后的指令,storebuffer会异步去将其他CPU的共享缓存置为失效,并更新缓存数据,最后同步数据到主内存,但在同步更新后的数据到主内存前,主内存的数据仍然可能会被其他CPU读取,所以会存在短暂的可见性问题
CPU层面提供了内存屏障指令来解决该问题

volatile是java提供的语言层面的内存屏障,他可以使得jvm和cpu不会对被volatile修饰的数据进行指令重排,同时被volatile关键字修饰的变量,在每个写操作之后,都会加入一条store内存屏障命令,此命令强制工作内存将此变量的最新值保存至主内存;在每个读操作之前,都会加入一条load内存屏障命令,此命令强制工作内存从主内存中加载此变量的最新值至工作内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值