zoukankan      html  css  js  c++  java
  • volatile 和 缓存一致性协议 mesi的关系

    在Java中,volatile是个很高层面的规范,保证了指令不会被重排序+对volatile变量的写使得当前cpu缓存中的所有变量写回到主存中,从而保证了内存可见性。

    具体的实现是靠JVM和cpu(还有操作系统?)合作实现的,不管cpu有没有mesi协议,用了volatile,JVM都会保证可见性,只不过实现方式是不一样的。

    有个问题就是:mesi似乎已经保证了线程之间的可见性,那么在实现了mesi协议的cpu上,volatile关键字其实是不是没用的?

    答案是:还是有用的,就算在实现了mesi的cpu上,volatile一样不可或缺。除了禁止指令重排序的作用外,由于mesi只是保证了L1-3 的cache之间的可见性,但是cpu和L1之间

    还有像storebuffer之类的缓存,而volatile规范保证了对它修饰的变量的写指令会使得当前cpu所有缓存写到被mesi保证可见性的L1-3cache中。(具体的实现,以X86体系为例,

    volatile会被JVM生成带lock前缀的指令)。

    扯两句远的:

    1、i++的问题是写更新丢失的问题,跟现在说的没关系,要用cas解决。

    2、cas其实不是原子性操作,要读一次,再写一次。但是可以用MESI实现原子性:读一次发现是目标值,写的时候判断是不是I就可以。mesi实现其他原子性操作也是这个思路。

    3、从2可以看出,悲观锁和乐观锁并不是对立的两件事,以数据库版本号实现乐观锁为例,update要锁行,这个又是悲观锁,而锁行(可能)要用cas去操作volatile变量,这又是乐观锁,然而底层mesi实现原子性的时候,写的时候需要知道现在的缓存行有没有失效,这就一定需要cpu核心之前有一个同步锁,这个又是悲观锁。所以纠结于名词是没有意义的,知道到底发生了什么事情更重要。

  • 相关阅读:
    Thread中的join使用
    java.lang.NoClassDefFoundError: Ljavax/enterprise/inject/spi/BeanManager;
    org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xm
    maven 中使用jstl 错误解决
    eclipse 安装maven
    前端 JS事件操作
    前端 JS
    前端 固定位置 与绝对定位
    前端 显示与隐藏
    前端 盒子阴影
  • 原文地址:https://www.cnblogs.com/chuliang/p/8206748.html
Copyright © 2011-2022 走看看