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),线程中对 ...
随机推荐
- Centos下安装git的web服务器
直接上代码 [Shell] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2 ...
- COM组件转换为.NET元数据
.net开发中,需要调用一些COM组件,COM组件的元素转化为.net的元数据后才能很好的调用. 下面贴出我转的过程. 首先,打开C:\Program Files (x86)\Microsoft SD ...
- python 3.6 urllib库实现天气爬取、邮件定时给妹子发送天气
#由于每天早上要和妹子说早安,于是做个定时任务,每天早上自动爬取天气,发送天气问好邮件##涉及模块:#(1)定时任务:windows的定时任务# 配置教程链接:http://b ...
- Ubuntu下安装Anaconda和tensorflow
官方指南:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/docs_src/install/install_linux. ...
- 中小企业为什么要上HR系统
人力资源不不过公司资源.也是一种社会资源. 越来越多的企业已将人作为一种重要的资源来看待,资金和技术则是其次.所以企业内部科学的全面的人力资源管理也因此处在了十分重要的位置上. 现在的人力资源是服务于 ...
- 第二十六天 蛰伏的Hibernate遇到春日的暖阳 —Spring MVC 集成Hibernate使用(一)
6月7日.晴."纷纷红紫已成尘,布谷声中夏令新. 夹路桑麻行不尽.始知身是太平人. " Hibernate和Spring的香艳相逢,不仅是Bean和Bean之间电光火 ...
- Android自己定义组件之日历控件-精美日历实现(内容、样式可扩展)
需求 我们知道.Android系统本身有自带的日历控件,网络上也有非常多开源的日历控件资源.可是这些日历控件往往样式较单一.API较多.不易于在实际项目中扩展并实现出符合详细样式风格的,内容可定制的效 ...
- 【CODEFORCES】 A. Dreamoon and Sums
A. Dreamoon and Sums time limit per test 1.5 seconds memory limit per test 256 megabytes input stand ...
- Java加载资源文件的两种方法
处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都需要与配置文件打交道.Java将配置文件当作一种资源(resource)来处理,并且提供了两 ...
- Struts2学习笔记整理(二)
这里是重点. Action接口 struts2 的Action可以是POJO 为了让用户开发的Action更加规范struts2提供了一个Action接口 ActionSupport基类 Struts ...