众所周知,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原则,比如:

  1. 程序次序原则,一个线程内,按照书写的顺序执行
  2. 锁定原则,lock前后执行
  3. volatile原则,volatile变量前后执行
  4. 传递原则,如果a需要调用b,那么a就会在b的前面

...

等等...

volatile的特性

volatile只能保证变量的可见性、有序性,但是不能保证原子性。因此可以用它来做double-check,但是不能来做i++的操作。如果想要实现i++的可靠性,必须依赖于synchronized、lock或者atomicXXX来实现。

参考

  1. 海子的《Java并发编程:volatile关键字解析》:http://www.cnblogs.com/dolphin0520/p/3920373.html
  2. liuxiaopeng的《Java 并发编程:volatile的使用及其原理》:https://www.cnblogs.com/paddix/p/5428507.html
  3. double check http://blog.csdn.net/dl88250/article/details/5439024
  4. cpu缓存知识:http://blog.jobbole.com/36263/

Volatile的作用的更多相关文章

  1. java中关键字volatile的作用

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...

  2. 转!!java中关键字volatile的作用

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...

  3. C++ volatile的作用

    volatile的作用     2006-10-23 13:44:21 大 中 小 关键在于两个地方:     1. 编译器的优化 (请高手帮我看看下面的理解) 在本次线程内, 当读取一个变量时,为提 ...

  4. restrict和volatile的作用

    每当看到这两个关键字,我都无比的头痛啊,当时看到理解了一下就明白了,但是在此遇到就忘记是怎么用的了,今天就索性写一写吧,好记性不如烂笔头呗,烂笔头不如存在网上. restrict是c99引入的,关键字 ...

  5. Java中volatile的作用以及用法

    volatile让变量每次在使用的时候,都从主存中取.而不是从各个线程的“工作内存”. volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正 ...

  6. Java中Volatile的作用

    Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...

  7. 18.1 volatile的作用

    volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值. 1.编译器的优化 在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一 ...

  8. Java内存模型及Java关键字 volatile的作用和使用说明

    先来看看这个关键字是什么意思:volatile  [ˈvɒlətaɪl] adj. 易变的,不稳定的; 从翻译上来看,volatile表示这个关键字是极易发生改变的.volatile是java语言中, ...

  9. java中关键字volatile的作用(转载)

    转载:http://blog.csdn.net/orzorz/article/details/4319055 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对 ...

随机推荐

  1. CCF-201412-1-门禁系统

    问题描述 试题编号: 201412-1 试题名称: 门禁系统 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况.每位 ...

  2. php命令执行脚本

    php -f jiaoben.php &  读入并解释指明的文件.

  3. fiddler安装及配置+利用fiddler进行简单抓包(wawayaya阅读)

    1.工欲善其事必先利其器,fiddler安装 https://www.telerik.com/fiddler 2.安装exe(无脑下一步) 3.安装成功后配置fiddler(因为启动fiddler时链 ...

  4. WinForm程序,实现只启动一个实例

    前言:在我们做的软件中,当点击图标运行时,正常的需求是只需要启动一个软件的实例,这是非常重要的一点,不然就显得我们的软件非常的山寨,笔者在工作中经常遇到同事没有注意这一点,看是不重要,实则非常的重要, ...

  5. 【Codeforces 837D】Round Subset

    http://codeforces.com/contest/837/problem/D 分解质因数,即第i个数的因子2的个数为c2[i],因子5的个数为c5[i],末尾零的个数就是min{Σc2[i] ...

  6. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

  7. db2服务器端授权

    昨天吃饭回来有点晚,没有及时写,今天补上.            db2服务器端安装就不说了,网上很多.今天具体说说授权吧.这是个麻烦事.            安装的时候会让你创建数据库.你就根据提 ...

  8. 自学Zabbix3.5.4-监控项item-History and trends

      历史和趋势是在Zabbix中存储收集数据的两种方法.然而,历史保持着每一个收集的价值,趋势保持每小时的平均信息,因此减少了对资源的需求. 1. 保留历史数据 我们可以通过如下方式来设置保留数据的时 ...

  9. 爬取豆瓣电影储存到数据库MONGDB中以及反反爬虫

    1.代码如下: doubanmoive.py # -*- coding: utf-8 -*- import scrapy from douban.items import DoubanItem cla ...

  10. 第五章 使用 SqlSession

    第五章 使用 SqlSession 原文链接; http://www.mybatis.org/spring/zh/sqlsession.html 在 MyBatis 中,你可以使用 SqlSessio ...