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),线程中对 ...
随机推荐
- Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇--纯前端多页面) @(HTML/JS) 一般来说,使用vue做成单页应用比较好,但特殊情况下,需要使用多页面也有另外 ...
- 如何在HTTP头中隐藏PHP版本号
PHP 配置默认允许服务器在 HTTP 响应头 X-Powered-By 中显示安装在服务器上的 PHP 版本.出于服务器安全原因(虽然不是主要的要担心的威胁),建议你禁用或隐藏此信息,避免那些针对你 ...
- php 写程序求三个数的最大值
最简单的调用PHP自带的max函数即可:echo max(1,2,3,4,5);如果要自定义函数的话:function test($a,$b,$c){ return $a > $b ?($a & ...
- 十大经典排序算法的JS版
前言 个人博客:Damonare的个人博客 如遇到问题或有更好的优化方法,可以: 提issue给我 或是pull requests 我都会看到并处理,欢迎Star. 这世界上总存在着那么一些看似相似但 ...
- UWP 用Thumb 控件仿制一个可拖动悬浮 Button
参考了 http://www.cnblogs.com/zhanggaoxing/p/6403430.html,并加以改进. 最终效果::: Thumb 的原生事件 DragStarted,DragDe ...
- codeforge免费下载账号 积分账号 共享账号
codeforge网站下载代码很好,没有积分怎么办?那么多好的matlab代码,matlab程序,C,JAVA等等,都要充值啊!!! 请用下面共享的codeforge账号密码========> ...
- centos yum install redis
linux下yum安装redis以及使用 1.yum install redis --查看是否有redis yum 源 [root@localhost ~]# yum install r ...
- .NET Core快速入门教程 2、我的第一个.NET Core App(Windows篇)
一.前言 本篇开发环境?1.操作系统: Windows 10 X642.SDK: .NET Core 2.0 Preview 二.安装 .NET Core SDK 1.下载 .NET Core下载地址 ...
- 行编辑距离Edit Distance——动态规划
题目描写叙述: 给定一个源串和目标串.可以对源串进行例如以下操作: 1. 在给定位置上插入一个字符 2. 替换随意字符 3. 删除随意字符 写一个程序.返回最小操作数,使得对源串进行这些操作后等 ...
- 豌豆夹Redis解决方式Codis源代码剖析:Proxy代理
豌豆夹Redis解决方式Codis源代码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描写叙述: Codis is a proxy b ...