mesi协议怎么实现_MESI缓存一致性协议小谈

MESI场景

下面这个程序缓存一致性问题,initFlag第二个线程更改为true后,如果没有volatile关键字修饰,thread1是无法可见数据已被修改,不会跳出while循环。

acdeaae1e85e025e0cf0ec9cb805f303.png
5253f1518b7b15315fe81da862046444.png

可见性实现一

当对代码initFlag进行修饰关键字volatile时,可实现数据修改的可见性

dbf1a101c90cc95511b7f8f610887e1f.png

可见性实现二

475f50074bc8fbdf68a2d3ffd4ec5155.png

如上图Console打印结果,很奇怪为什么initFlag没有被volatile修饰也可以实现initFlag变量的可见性,那是为什么呢?为什么线程1能够将自己的工作内存副本清除去主内存获取到线程2更改后的值呢?(不用volatile关键字)

答案是MESI缓存一致性协议的原理所致,当MESI收到一个#LOCK汇编指令时,会强制所有的线程的副本数据进行数据同步,那#LOCK汇编指令在Java中,是如何体现出来,自然是synchronized。

我们只是增加了一行,就实现了volatile的功能

System.out.println("进来了");

我们看下源码就知道了

/** * Prints a String and then terminate the line. This method behaves as * though it invokes {@link #print(String)} and then * {@link #println()}. * * @param x The String to be printed. */ public void println(String x) { synchronized (this) { print(x); newLine(); } }

源码里有synchronized同步代码块,在线程中存在同步块时,会强制去主内存重新获取主内存的值 可以试下把线程1的while循环里的System.out.println()改为普通的赋值语句int a = 0;则线程1会卡住死循环。

小结

MESI的数据同步条件为收到一个#LOCK汇编指令时,就会进行线程中的副本数据同步,而上面的例子中,只是用了一个取巧的案例来说明其中的缘由。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值