Volatile的作用
众所周知,volatile关键字可以让线程的修改立刻通知其他的线程,从而达到数据一致的作用。那么它具体涉及到哪些内容呢?
关于缓存
计算机最大的存储空间就是磁盘(硬盘),但是访问的速度也是最慢的,价格最便宜;再就是内存,容量更小,造价更高,但是速度也更快。不过跟cpu的计算速度比起来,那就太慢了。可以想像,如果cpu每次计算都要从内存读取数据,那大部分的时间估计都浪费在这上面了。所以就引入了缓存的概:

缓存的结构大概时这样的,从1级到3级速度越来越慢,最后通过总线与内存连接。如果时多核多cpu,那么结构大概是这样的:

多线程造成的缓存不一致
由于现在大部分的机器都有多个cpu,这就导致如果时运行多线程的任务,就可能运行在不同的cpu上。试想一下:
int a = 0;
int b = a;
b += 1;
如果开启两个线程执行,我们想要的结果是3,但是最后的结果只是2。这是因为在做加法运算的时候,cpu会先把a的值读入cpu的缓存,然后更新缓存,在更新内存。很有可能两个线程分散在两个cpu,每个都是对自己缓存内的数据进行读写,这样就造成了结果不一致的现象。
volatile的作用
volatile的作用就是当一个线程更新某个volatile声明的变量时,会通知其他的cpu使缓存失效,从而其他cpu想要做更新操作时,需要从内存重新读取数据。具体的通知方式,一种是通过某种协议,比如MESI;再就是对总线加锁,控制变量的读取。具体硬件上怎么个流程,我就搞不清楚了...
并发
这里还需要强调的时,并发编程涉及的三个特性:原子性、可见性、有序性。就好像分布式里面的cap一样,需要熟知。先来通俗的描述下:
原子性
即要么全做,要么全部做。比如从a银行转钱到b银行。
在编程中,除了long或者double外的变量更新就是原子操作。long和double除外,是因为它们在32位的操作系统上,会被分成两部分进行更新,此时就不是原子的。
再比如最常见的i++也不是原子的,它相当于先读取i,进行+1操作,更新三个步骤进行。
可见性
多个线程访问同一个变量时,这个变量被修改后,能被其他的线程看到。
有序性
比如
int a = 10;
int r = 2;
a = a + 3;
r = a*a;
这段代码有可能进行指令的重排,从而导致结果跟预期的不一致。指令的重排需要按照happens-before原则,比如:
- 程序次序原则,一个线程内,按照书写的顺序执行
- 锁定原则,lock前后执行
- volatile原则,volatile变量前后执行
- 传递原则,如果a需要调用b,那么a就会在b的前面
...
等等...
volatile的特性
volatile只能保证变量的可见性、有序性,但是不能保证原子性。因此可以用它来做double-check,但是不能来做i++的操作。如果想要实现i++的可靠性,必须依赖于synchronized、lock或者atomicXXX来实现。
参考
- 海子的《Java并发编程:volatile关键字解析》:http://www.cnblogs.com/dolphin0520/p/3920373.html
- liuxiaopeng的《Java 并发编程:volatile的使用及其原理》:https://www.cnblogs.com/paddix/p/5428507.html
- double check http://blog.csdn.net/dl88250/article/details/5439024
- cpu缓存知识:http://blog.jobbole.com/36263/
Volatile的作用的更多相关文章
- java中关键字volatile的作用
用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...
- 转!!java中关键字volatile的作用
用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...
- C++ volatile的作用
volatile的作用 2006-10-23 13:44:21 大 中 小 关键在于两个地方: 1. 编译器的优化 (请高手帮我看看下面的理解) 在本次线程内, 当读取一个变量时,为提 ...
- restrict和volatile的作用
每当看到这两个关键字,我都无比的头痛啊,当时看到理解了一下就明白了,但是在此遇到就忘记是怎么用的了,今天就索性写一写吧,好记性不如烂笔头呗,烂笔头不如存在网上. restrict是c99引入的,关键字 ...
- Java中volatile的作用以及用法
volatile让变量每次在使用的时候,都从主存中取.而不是从各个线程的“工作内存”. volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正 ...
- Java中Volatile的作用
Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...
- 18.1 volatile的作用
volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值. 1.编译器的优化 在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一 ...
- Java内存模型及Java关键字 volatile的作用和使用说明
先来看看这个关键字是什么意思:volatile [ˈvɒlətaɪl] adj. 易变的,不稳定的; 从翻译上来看,volatile表示这个关键字是极易发生改变的.volatile是java语言中, ...
- java中关键字volatile的作用(转载)
转载:http://blog.csdn.net/orzorz/article/details/4319055 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对 ...
随机推荐
- HDU4508--完全背包
湫湫系列故事--减肥记I Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- Mysql 的 IF 判断
mysql自带很多判断逻辑,今天说一说IF的判断语句,正好今天做项目的时候也用到了 1. IF 判断 IF判断和我们代码里面写的有略微的差别,举个例子 IF('表达式','结果1','结果2') 如 ...
- Vux配置指南
流程 Vux是Vue.js的一个ui库,官网在这里,官方文档的配置指南侧重于技术的罗列,我这里简化一下Vux的配置流程. 1. 安装vux npm install vux --save 2. 安装le ...
- ios7 以后准确获取iphone设备的MAC(物理地址)
通过参考 钉钉 项目,知道是通过wifi拿到路由的MAC地址.那么可不可以拿到iphone 设备的MAC 地址呢? 经过一番搜索,发现所有文章都是针对 ios 7 以前 可以拿到. 而且方法也都是同一 ...
- 认知服务调用如何使用图片的DataURL
说明: Data URL给了我们一种很巧妙的将图片"嵌入"到HTML中的方法.跟传统的用img标记将服务器上的图片引用到页面中的方式不一样,在Data URL协议中,图片被转换成b ...
- python3.6 urllib.request库实现简单的网络爬虫、下载图片
#更新日志:#0418 爬取页面商品URL#0421 更新 添加爬取下载页面图片功能#0423 更新 添加发送邮件功能# 优化 爬虫异常处理.错误页面及空页面处理# 优化 爬虫关键字黑名单.白名单,提 ...
- mvc 中Range中max和min值晚绑定
对于Attribute : Range(min,max)的min和max必须在用的时候给,但是需求有时须要把这两个值存db.动态取出的.这时就须要razor帮忙了: @Html.TextBoxFor( ...
- Windows 下Oracle database 9i 64bit 仅仅有 Windows Itanium 64bit
Windows 下Oracle database 9i 64bit 仅仅有 Windows Itanium 64bit,没有Windows x86-64bit的 详细请见例如以下的certificat ...
- HTML中在a标签中添加onclick事件
1.链接的onclick 事件被先执行,其次是href属性下的动作; 2.假设链接中同时存在href 与onclick,如果想让href 属性下的动作不执行,onclick 必须得到一个false的返 ...
- A 01 如何理解会计中的借和贷
敲黑板,上结论: 借:钱花到哪里去了? 贷:钱从哪里搞来的? 举个例子 某公司用银行存款200 000元购入一辆自用小汽车(自用小汽车属于固定资产), 会计里面如何计呢? 答案: 借:固定资产200 ...