1.保证内存可见性

通俗来说就是,线程A对一个volatile变量的修改,对于其它线程来说是可见的,即线程每次获取volatile变量的值都是最新的。

当一个变量被 volatile 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据。

   在线程内, 当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后,再取变量值时,就直接从寄存器中取值;当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致。
   

  当变量在因别的线程等而改变了值,该寄存器的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致。
  当该寄存器在因别的线程等而改变了值,原变量的值不会改变,从而造成应用程序读取的值和实际的变量值不一致。

volatile的本质:

volatile应该解释为“直接存取原始内存地址”比较合适,“易变的”这种解释简直有点误导人。

综上所述,频繁地使用volatile很可能会增加代码尺寸和降低性能,但它却可以保证程序的正确性,所以在合适的地方使用volatile关键字是必要的。

*************************************************************************************

1)使用中断改变对象值的情况

  我们在中断服务程序中操作了某个对象,比如谁改变了一个变量的值。而在其它程序中我们希望通过这个变量值得改变去进行一些操作。在这个时候,我们使用或者不使用volatile关键字,可能得到截然不同的结果。

  如果我们将变量定义为:static int var=0; ,然后再中断服务成勋中将其修改为:var=1,但是在另一函数中使用它但不会修改它,那么编译器会认为它没有变化,从而直接使用寄存器中的副本。

  如果我们将变量定义为:volatile int var=0;,那么结果就完全不同了,每次在函数中使用var变量时,都会重新读取,而不会使用寄存器中的副本。

(2)多任务共享标志的情况

  多任务共享时,其实也是一样的,在一个任务中修改了一个对象后,在另一个对象中应用它,但编译器并没发现在该任务中对它有修改。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。从而并不能响应在另一任务下的变化。

  在这种情况下,一般我们都需要使用volatile关键字来定义任务间共享的标识。

3)硬件寄存器内存映射的情况

  内存映射的情况是非常多的,比如我们将外设的寄存器映射到内存的某一段区域;再比如我们同过DMA方式将数据直接写到内存中的某一段区域。

由于我们外部的数据都是直接进入了内存区域,而程序知识引用它的值。编译器优化时可能就直接采用寄存器中的副本了。佷显然这不是我们需要的结果,这时将这段内存对应的变量声明为volatile,则可以保证我们的需求。

*************************************************************************************

C语言volatile的本质(三十四)相关推荐

  1. c语言三级上机题库,2006年9月全国等级考试三级c语言上机题库(三十四)

    ★☆题目34(无忧id 73,102 素数题) 无忧id 102 题提供了求素数isPrime()函数 程序prog1.c的功能是:选出100以上1000之内所有个位数字与十位数字之和被10除所得余数 ...

  2. 三十四、深入Java中的泛型(上篇)

    @Author:Runsen @Date:2019年10月22日 19:39:21 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件 ...

  3. [Python人工智能] 三十四.Bert模型 (3)keras-bert库构建Bert模型实现微博情感分析

    从本专栏开始,作者正式研究Python深度学习.神经网络及人工智能相关知识.前一篇文章开启了新的内容--Bert,首先介绍Keras-bert库安装及基础用法及文本分类工作.这篇文章将通过keras- ...

  4. 【零基础学Java】—Calendar类(三十四)

    [零基础学Java]-Calendar类(三十四) java.util.Calendar日历类 Calendar类是一个抽象类,里面提供了很多操作日历字段的方法 Calendar类无法直接创建对象,里 ...

  5. Android 天气APP(三十四)语音搜索

    上一篇:Android 天气APP(三十三)语音播报 语音搜索 前言 正文 一.权限配置 二.用户体验优化 三.配置语音识别听写 四.语音搜索 五.地图天气添加语音搜索功能 六.城市搜索添加语音搜索功 ...

  6. [转载]三十四个有趣的小故事

    [转载]三十四个有趣的小故事 一. 用人之道 去过庙的人都知道,一进庙门,首先是弥陀佛,笑脸迎客,而在他的北面,则是黑口黑脸的韦陀.但相传在很久以前,他们并不在同一个庙里,而是分别掌管不同的庙.弥乐佛 ...

  7. 第三十四章 数论——高斯消元解线性方程组

    第三十四章 数论--高斯消元解线性方程组 一.高斯消元 1.线性方程组 2.高斯消元步骤 (1)数学知识铺垫 增广矩阵和阶梯矩阵 初等变换 (2)高斯消元步骤 二.代码模板 1.问题: 2.代码 一. ...

  8. c语言int型等长输出,c语言先程序设计15第十四讲第六章下.ppt

    c语言先程序设计15第十四讲第六章下 高级语言程序设计 主讲教师:贾彩燕 计算机与信息技术学院 计算机科学与技术系 cyjia@ 第六章 数组 主要内容 数组的概念.定义和使用 数组程序实例 数组作为 ...

  9. 程序员编程艺术第三十四~三十五章:格子取数问题,完美洗牌算法

    第三十四~三十五章:格子取数,完美洗牌算法 作者:July.caopengcs.绿色夹克衫.致谢:西芹_new,陈利人, Peiyush Jain,白石,zinking. 时间:二零一三年八月二十三日 ...

最新文章

  1. python在bim中的应用_Revit元素类别——Dynamo Python系列教程(六)
  2. 请简述php循环控制语句,PHP 循环控制语句几种方法详解_PHP教程
  3. 自动添加html结束标志,HTML:包含或排除可选的结束标记?
  4. CPU-内存-IO-网络调优
  5. 力扣116. 填充每个节点的下一个右侧节点指针(C++,附思路)
  6. 车险受益人变更需要什么资料?
  7. 《TensorFlow 2.0深度学习算法实战教材》学习笔记(八、过拟合)
  8. 不容错过 DOCKERCON SF 2019 大会的 5 个理由
  9. Xml 学习 ---引自MSDN CHINA
  10. 利用Quartz2D--context绘制矩形
  11. websocket 发送多条消息如何判断全部接收_Websocket的分布式集群开发及部署
  12. linux下查看使用的显示服务器类型
  13. Activemq 下载地址
  14. mess组网 中继_想全屋覆盖还用中继器?out啦!Mesh组网才是最佳方案
  15. Win10 文件夹删不掉,提示需要来自XXX的权限才能对此文件夹进行更改
  16. 绿地集团总裁张玉良谈到接班人的条件:
  17. 北大韦神等十人获奖,均分1000万元,达摩院2021青橙奖出炉
  18. 取消检验批过账(取消检验批UD判定到Rerel,再把非限性库存转到质检库存,然后就可以取101收货了)
  19. Linux服务篇之远程访问及控制SSH
  20. 脱离实际,技术就是屠龙之技

热门文章

  1. 如何实现百万TPS?详解JMQ4的存储设计
  2. 从字节码层面,解析 Java 布尔型的实现原理
  3. lvm讲解与磁盘挂载问题排除
  4. 聊聊spring for kafka对consumer的封装与集成
  5. Codeforces Round #296 (Div. 2)
  6. js作为参数,并且返回值;js的回调模式 callback
  7. (风中奇缘) Pocahontas
  8. Spark开源学习模块
  9. jQuery加载js脚本
  10. CenterNet :Objects as Points 详解