Java 并发编程之volatile关键字解析
摘录
1、
计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。
Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。
2、
要想并发程序正确地执行,必须要保证原子性、可见性(缓存一致性问题)以及有序性(指令重排序问题)。只要有一个没有被保证,就有可能会导致程序运行不正确。
- 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
- 可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
- 有序性:即程序执行的顺序按照代码的先后顺序执行。
3、
Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现。
Java提供了volatile关键字来保证可见性。另外,通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。
在Java里面,可以通过volatile关键字来保证一定的“有序性”,另外可以通过synchronized和Lock来保证有序性,此外,Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为 happens-before 原则。
4、
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值(包括修改和写入主存两个操作,使用volatile关键字会强制将修改的值立即写入主存),这新值对其他线程来说是立即可见的(使其他线程的工作内存中该变量的值无效,从而重新从内存读取)。
2)禁止进行指令重排序。
即volatile保证可见性和一定程度的有序性,但不保证原子性。
volatile的原理和实现机制:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
参考资料
http://www.cnblogs.com/dolphin0520/p/3920373.html(强烈推荐)
Java 并发编程之volatile关键字解析的更多相关文章
- Java并发编程之volatile关键字解析
一内存模型的相关概念 二并发编程中的三个概念 三Java内存模型 四深入剖析volatile关键字 五使用volatile关键字的场景 volatile这个关键字可能很多朋友都听说过,或许也都用过.在 ...
- Java并发编程之volatile关键字
大概是因为项目.业务的原因,工作上几乎还没有使用过多线程相关的功能,相关知识差不多都忘了,所以最近补一下基础. volatile用来修饰共享变量,volatile变量具有 synchronized 的 ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- (转)Java并发编程:volatile关键字解析
转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...
- Java并发编程:volatile关键字解析(转载)
转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 ...
- Java并发编程:volatile关键字解析-转
Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...
- Java并发编程:volatile关键字解析(学习总结-海子)
博文地址:Java并发编程:volatile关键字解析
- 6、Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- 转:Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字, ...
随机推荐
- SpringMVC学习--json
简介 json数据格式在接口调用中.html页面中较常用,json格式比较简单,解析还比较方便.比如:webservice接口,传输json数据. springmvc与json交互 @RequestB ...
- Learning jQuery, 4th Edition 勘误表
来源于:http://book.learningjquery.com/3145/errata/ Chapter 1 page 14 The CSS snippet is correct, but it ...
- SQL SERVER 2008向ORACLE 11G迁移示例
来源于:http://www.cnblogs.com/hiizsk/ 由SQL SERVER 2008向ORACLE 11G迁移过程记录之一-表 使用Oracle Sql Developer将SQL ...
- Mybatis 异常: The content of elements must consist of well-formed character data or markup
原因很简单:在ibatis的配置文件中不能出现小于号(>) <delete id="deleteByPrimaryKey" parameterType=&quo ...
- Servlet作业1-实现注册登录
1,注册功能 注册页面zhuce.html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &q ...
- 【BZOJ 4517】【SDOI 2016 Round1 Day2 T2】排列计数
本蒟蒻第一次没看题解A的题竟然是省选$Round1$ $Day2$ $T2$ 这道组合数学题. 考试时一开始以为是莫队,后来想到自己不会组合数的一些公式,便弃疗了去做第三题,,, 做完第三题后再回来看 ...
- mysql5.5的安装与配置(亲测版)
mysql5.5.x的编译安装 说明:5.5和5.1差不多,只是在编译时增加了一个cmake,其他基本一样,mysql5.5默认编码是utf-8,在使用mysql5.5配置lnmp或者lamp后安装d ...
- CMY/CMYK 打印机色彩
CMY 发光物体和反光物体产生颜色的机制不同. 前者指光源光, 它的颜色由发光波长决定. 后者指不能发光但却能表现出颜色的物体, 例如色素. 色素的颜色由它不能吸收的光的波长决定. 比如红色色素, 除 ...
- GIF/PNG/JPG和WEBP/base64/apng图片优点和缺点整理
GIF/PNG/JPG/WEBP/APNG都是属于位图(位图 ,务必区别于矢量图): GIF/PNG和JPG这三种格式的图片被广泛应用在现今的互联网中,gif曾在过去互联网初期慢速的情况下几乎是做到了 ...
- AOP 注入失败的问题
启用了AOP 后,报这样的类似错误: Error creating bean with name 'bpmpSysUserService': Injection of autowired depend ...