zoukankan      html  css  js  c++  java
  • "Loads are not reorderd with other loads" is a FACT!! 续:不要指望 volatile

    上一篇随笔中提到了volatile,实际上由于上一篇中提到的问题,volatile已经越来越远离其应有的含义了。在说这个问题之前,我们又要提.NET的内存模型问题(以下简称MM),我不指望在这里长篇大论的说其内存模型是如何的。简单的说就是以下的几句话:

    第一、load与store之间的数据依赖关系不会被改变

    第二、所有的store操作都有release语义,所有的volatile的load都有acquire语义,

    第三、所有的load与store都不能跨越memory barrier(full fence,全内存栅栏)

    第四、load和store仅仅在紧邻的对于相同位置的load和store存在时才可能被移除。

    所谓acquire与release是怎么一回事,这个~acquire可以理解为,没有其他的操作(对内存的)可以将自己执行的顺序调整到它之前;相反的,release可以理解为,没有其他的操作可以将自己的执行调整到它之后。但是请注意!acquire和release已经是半个内存栅障了!他应该对CPU的可见性产生影响。好,我们先不提这个,假设MS目前的x86, x64上的.NET的MM是完美实现的。看看MSDN对volatile的解释是什么:

    第一句:

    The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time.

    这句实际上没有说任何的实际内容。

    第二句:

    Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread.

    这句指出了volatile的一个作用--防止编译器优化你的代码,虽然提到了编译器对于volatile不再认为是单线程访问的,但是仅仅是assume,这并不能解决任何问题。

    第三句:

    This ensures that the most up-to-date value is present in the field at all times.

    这是什么?这完全说明了我们上面所说的volatile的作用:volatile的load具有release语义!

    第四句:

    The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access.

    实际上他想说,如果你向volatile中执行了store,那么你在load中(即使在另一个线程)也会获得most up to date的值。这样我们就不必使用lock再引入同步或者memory fence了。

    好了,按照上面的解释,如果.NET的MM是完美实现了的,OK,全部说得过去!但是请看上一篇随笔,不是的!volatile根本不能保证load是acquire的!也就是,Microsoft的.NET Framework在x86与Intel 64的平台下的实现是有漏洞的(这跟Intel一点没有关系,不要误会,是.NET的MM的问题)!因此,不要指望MSDN的解释了。在你书写Multi-thread Application的时候,还是多留一个心眼吧。

    如果要修补这个漏洞,那么volatile的load需要半个memory fence,但是请看看x86,x64的文档,你就知道,这里不得不要一个full fence。也就是,volatile的load是完全不会被reorder的,这合适么?我不知道,我不知道真正的Java MM的官方解释在哪里,但是目前至少有文档表明,Java的volatile是一个full fence。

    最后,我想说明一点。大部分战友们,大部分时间内,根本不用为这个操心劳神。Please don't be panic:-)

  • 相关阅读:
    iOS UITextField限制输入长度
    SpringBoot 统一异常处理
    idea+springboot+freemarker热部署
    JAVA 实现链表
    mysql 添加新用户 赋予权限
    Spring MVC 集成 Redis集群
    js获取当前日期时间及其它操作
    MySQL Error Codes MYSQL的错误代码
    js数组 删除元素
    JS table form 序列化提交
  • 原文地址:https://www.cnblogs.com/lxconan/p/1246776.html
Copyright © 2011-2022 走看看