• volatile特性及内存语义


    1.volatile变量自身具有下列特性:
    ·可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
    ·原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。

    2.volatile-建立的happens-before关系 :

    从内存语义的角度来说,volatile的写-读与锁的释放-获取有相同的内存效果:

                                      volatile写和锁的释放有相同的内存语义;

                                      volatile读与锁的获取有相同的内存语义。

    3.volatile-的内存语义 :

    写:当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存

    读:当一个volatileJMM会把该线对应的本地内存置无效线程接下来将从主内存中取共享
     

    4.语义总结:

    ·线A写一个volatile量,实质上是线A向接下来将要读这volatile量的某个线程发出了(其共享量所做修改的)消息。
    ·线B一个volatile量,实质上是线B接收了之前某个线出的(在写volatile变量之前共享量所做修改的)消息。
    ·线A写一个volatile量,随后线B读这volatile量,实质上是线A过主内存向线B送消息。 
    5.JMM内存屏障插入策略:

    ·在每个volatile写操作的前面插入一个StoreStore屏障(禁止上面的普通写和下面的volatile写重排序)。

    个人见解:每次volatile写操作后都要将本地内存刷新到主内存,所以这里如果不加屏障禁止重排序就可能导致共享变量无法及时对所有线程可见。

    ·在每个volatile写操作的后面插入一个StoreLoad屏障(禁止上面的volatile写与下面可能有的volatile读/写重排序)。

    ·在每个volatile操作的后面插入一个LoadLoad屏障(禁止下面所有的普通读写操作和上面的volatile读重排序)和一个LoadStore屏障(禁止下面所有的普通写操作和上面的volatile读重排序)
     个人见解:每次volatile读之前都要将本地内存舍弃去主内存获取最新数据,加屏障禁止重排序的作用是为了保证下面的普通读写的数据不会被舍弃。

     

  • 相关阅读:
    通过系统配置来提高ASP.NET应用程序的稳定性
    设置localhost文件
    打击啊,看过的东西怎么就记不住呢???
    用.Net开发Windows服务初探
    在项目中设立里程碑有哪些好处&基础架构的开发任务&试运行的部署
    C#中构造函数和析构函数的用法
    ASP.NET1.0升级ASP.NET2.0的问题总结
    误删Oracle数据库实例的控制文件
    Embedding Google Earth in a C# Application (转载)
    教你如何克隆Oracle 10g数据库,冷备份方式(图文版)(转载)
  • 原文地址:https://www.cnblogs.com/AmbitiousMice/p/8383946.html
Copyright © 2020-2023  润新知