volatile的作用和原理
1、保持内存可见性
内存可见性:所有线程都能看到共享内存的最新状态。每次读取前必须先从主内存刷新最新的值。每次写入后必须立即同步回主内存当中。
Java通过几种原子操作完成工作内存和主内存的交互:
lock:作用于主内存,把变量标识为线程独占状态。
unlock:作用于主内存,解除独占状态。
read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。
volatile如何保持内存可见性
volatile的特殊规则就是:
read、load、use动作必须连续出现。
assign、store、write动作必须连续出现。
所以,使用volatile变量能够保证:
每次读取前必须先从主内存刷新最新的值。每次写入后必须立即同步回主内存当中。也就是说,volatile关键字修饰的变量看到的随时是自己的最新值。
2、防止指令重排
volatile关键字提供内存屏障的方式来防止指令被重排,编译器在生成字节码文件时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
基于保守策略的JMM内存屏障插入策略:
在每个volatile写操作的前面插入一个StoreStore屏障。
在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。
在每个volatile读操作的后面插入一个LoadStore屏障。
对volatile变量的单次读/写操作可以保证原子性的,如long和double类型变量,但是并不能保证i++这种操作的原子性,因为本质上i++是读、写两次操作。
volatile不能完全取代Synchronized的位置,只有在一些特殊的场景下,才能适用volatile。总的来说,必须同时满足下面两个条件才能保证在并发环境的线程安全:
(1)对变量的写操作不依赖于当前值。
(2)该变量没有包含在具有其他变量的不变式中。
volatile的作用和原理的更多相关文章
- synchronized与volatile的区别及各自的作用、原理(学习记录)
synchronized与volatile的区别,它们的作用及原理? 说到两者的区别,先要了解锁提供的两种特性:互斥(mutual exclusion) 和可见性(visibility). 互斥:即一 ...
- volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...
- 面试题:volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例. 而发挥神奇作用的volatile,可以当之无愧的被称为Java ...
- Volatile的作用
众所周知,volatile关键字可以让线程的修改立刻通知其他的线程,从而达到数据一致的作用.那么它具体涉及到哪些内容呢? 关于缓存 计算机最大的存储空间就是磁盘(硬盘),但是访问的速度也是最慢的,价格 ...
- Java 并发编程:volatile的使用及其原理
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- 【Java并发编程】11、volatile的使用及其原理
一.volatile的作用 在<Java并发编程:核心理论>一文中,我们已经提到过可见性.有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果 ...
- 【转】Java 并发编程:volatile的使用及其原理
一.volatile的作用 在<Java并发编程:核心理论>一文中,我们已经提到过可见性.有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果 ...
- Java 并发编程:volatile的使用及其原理(二)
一.volatile的作用 在<Java并发编程:核心理论>一文中,我们已经提到过可见性.有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果 ...
- volatile的使用及其原理
1. volatile的作用 相比Sychronized(重量级锁,对系统性能影响较大),volatile提供了另一种解决 可见性和有序性 ???问题的方案.对于原子性,需要强调一点,也是大家容易误解 ...
随机推荐
- Luogu 2737 [USACO4.1]麦香牛块Beef McNuggets
NOIP2017 D1T1 的结论,两个数$a, b$所不能表示出的最大的数为$a * b - a - b$. 听了好几遍证明我还是不会 注意到本题中给出的数都非常小,所以最大不能表示出的数$\leq ...
- oracle创建数据库的语句
首先 oracle严格来说表空间的概念和数据库的概念很像,为了理解的方便我们,可以把表空间就先当成数据库 我们在安装oracle的服务端的时候默认会安装一些,默认实例 1.建立表空间,现在解释下面语句 ...
- GDB中应该知道的几个调试方法【转陈浩】
七.八年前写过一篇<用GDB调试程序>, 于是,从那以后,很多朋友在MSN上以及给我发邮件询问我关于GDB的问题,一直到今天,还有人在问GDB的相关问题.这么多年来,有一些问题是大家反复 ...
- SQL XML示例
declare @xmlDoc xml,@id varchar(50); set @xmlDoc='<DocObjContent> <NewCtrl Id="0001&qu ...
- 使用pip安装离线包
为了方便以后查看,特总结于此: 下载离线安装包并放到你想放的文件目录下 使用anaconda prompt安装离线文件 如果没有安装anaconda,则参照下边链接里边的操作!!! 离线环境通过pip ...
- AI进阶之路
一.方法论 二.发展趋势 三.入门查看 1. https://hongyuxie.github.io/MyResume_CN/ 上班后大家还刷算法题吗 编程面试的 10 大算法概念汇总 技术面试宝典: ...
- 【bzoj2242】: [SDOI2011]计算器 数论-快速幂-扩展欧几里得-BSGS
[bzoj2242]: [SDOI2011]计算器 1.快速幂 2.扩展欧几里得(费马小定理) 3.BSGS /* http://www.cnblogs.com/karl07/ */ #include ...
- HDU4624 Endless Spin(概率&&dp)
2013年多校的题目,那个时候不太懂怎么做,最近重新拾起来,看了一下出题人当初的解题报告,再结合一下各种情况的理解,终于知道整个大致的做法,这里具体写一下做法. 题意:给你一段长度为[1..n]的白色 ...
- luogu2513 逆序对数列
我们令\(f[i][j]\)表示\(i\)的全排列中,逆序数为\(j\)的个数. 我们考虑在\(i-1\)的排列中插入\(i\).\(k\)是这次更新会导致增加多少逆序数. 则\(\begin{ali ...
- node 后台搭建笔记
*注:本文是个人记录,非常粗略 1.建立server服务的文件被单独放置在一个文件夹下或最外层 2.src文件包含:controller/model/routes 文件夹 和 app.js文件