【深入理解并发编程系列3】JMM-CPU缓存一致性协议MESI

volatile可见性实现的原理

编译后的汇编会增加一个lock前缀

CPU指令

lock前缀是总线锁

图片

CPU访问内存必须通过总线桥访问。lock前缀加了总线锁,其他CPU就无法通过总线桥获取内存数据。

这个是古老的CPU用的。这种方式会降低多核性能。

MESI

图片

M:modify
E:独占
S:share
I:已失效

总线嗅探:

CPU会嗅探Bus总线的通知状态。

当CPU都要进行对某个缓存行进行加锁的时候(64byte)会发一个消息出来。我要加锁了。让总线来判断,是否加锁成功。总线裁决。

LOCK的时候告诉CPU采用缓存一致性协议来处理这个被修饰的变量。

缓存行是最大64byte有时候变量大于64byte,这时候会升级总线锁。

缓存一致性协议无法对寄存器生效。所以如果已经被加载到了寄存器里面进行操作的话

CPU中有一个 StoreBufer。cpu修改变量后,会发送一个I信号给其他cpu,其他cpu信息收到后确认后会回复一个已经失效消息。这时后才进行storo操作。所以会先把操作后的数据存在storeBuffer.(内部CPU的ACK机制)

接收后 storeBuffer放回缓存行,在写到内存。

Happens-before

指令重排需要遵循的规则。

Thread().start
Thread().interupt
这种是不会被重排的

八大规则:
图片