并发系列(三)-----volatile
一 简介
volatile关键字是轻量级的synchronized,volatile在并发编程中保证共享变量的可见性,当一个线程修改被volatile修饰的共享变量时,另外一个线程就能读到这个修改的值。volatile可以保证共享变量的可见性但不能保证复合操做的原子性:比如像i++这样的操做是volatile是不能保证的。
二 volatile变量的特性
被volatile修饰的变量有两种特性
1.保证此变量对所有线程的可见性,可见性是指当一条线程修改了这个变量的值,新的值对于其它是可以立即的得知的。虽然volatile对变量有可见性的特点,但是volatile并不能保证volatile++这样的操做在并发下是安全的。在深入理解Java虚拟机里面作者从字节码的角度解释了不安全的原因。具体的描述看书就可以了。下面是我的理解,volatile保证的变量读和写(对于不理解volatile的读写的内存语义的下面会讲到)的时候是安全的但是并不能保证对变量的操做是线程安全。什么意思呢,就是在i++的这样的操做JVM不只是从内存(指的是JMM的内存)中获取值和存入值还做了其他的操做,比如iadd,当它执行像iadd这样的操做时其他线程可能将值已经修改了,而此时当前线程是没有执行获取操做的所以在当前线程操作的还是旧值。对比JMM理解会比较容易理解一点。
2.禁止指令重排序关于重排序的问题看上一篇文章JMM。
三 volatile内存语义
1.volatile的读写内存语义
volatile写的内存语义: 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存
volatile读的内存语义: 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量
2.volatile的内存语义的实现
为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能。为此,JMM采取保守策略。下面是基于保守策略的JMM内存屏障插入策略
在每个volatile写操作的前面插入一个StoreStore屏障。
在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。
在每个volatile读操作的后面插入一个LoadStore屏障。
如图


上图中的StoreStore屏障可以保证在volatile写之前,其前面的所有普通写操作已经对任意处理器可见了。这是因为StoreStore屏障将保障上面所有的普通写在volatile写之前刷新到主内存。
这里比较有意思的是,volatile写后面的StoreLoad屏障。此屏障的作用是避免volatile写与后面可能有的volatile读/写操作重排序。因为编译器常常无法准确判断在一个volatile写的后面是否需要插入一个StoreLoad屏障(比如,一个volatile写之后方法立即return)。为了保证能正确实现volatile的内存语义,JMM在采取了保守策略:在每个volatile写的后面,或者在每个volatile读的前面插入一个StoreLoad屏障。从整体执行效率的角度考虑,JMM最终选择了在每个volatile写的后面插入一个StoreLoad屏障。因为volatile写-读内存语义的常见使用模式是一个写线程写volatile变量,多个读线程读同一个volatile变量。当读线程的数量大大超过写线程时,选择在volatile写之后插入StoreLoad屏障将带来可观的执行效率的提升。从这里可以看到JMM在实现上的一个特点:首先确保正确性,然后再去追求执行效率。
参考文档:
<< Java并发编程艺术>>方腾飞 魏鹏 程晓明
<<深入理解Java虚拟机:JVM高级特性与最佳实践>>周志明
并发系列(三)-----volatile的更多相关文章
- 系统学习java高并发系列三
转载请注明原创出处,谢谢! 首先需要说说线程安全?关于线程安全一直在提,比如StringBuilder和StringBuffer有什么区别? 经常就会出现关于线程安全与线程非安全,可能一直在提自己没有 ...
- java并发系列(三)-----ReentrantLock(重入锁)功能详解和应用演示
1. ReentrantLock简介 jdk中独占锁的实现除了使用关键字synchronized外,还可以使用ReentrantLock.虽然在性能上ReentrantLock和synchronize ...
- 干货:Java并发编程系列之volatile(二)
接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ...
- java高并发系列 - 第7天:volatile与Java内存模型
public class Demo09 { public static boolean flag = true; public static class T1 extends Thread { pub ...
- MySQL并发复制系列三:MySQL和MariaDB实现对比
http://blog.itpub.net/28218939/viewspace-1975856/ 并发复制(Parallel Replication) 系列三:MySQL 5.7 和MariaDB ...
- Java 并发编程:volatile的使用及其原理
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析
学习Java并发编程不得不去了解一下java.util.concurrent这个包,这个包下面有许多我们经常用到的并发工具类,例如:ReentrantLock, CountDownLatch, Cyc ...
- java高并发系列-第1天:必须知道的几个概念
java高并发系列-第1天:必须知道的几个概念 同步(Synchronous)和异步(Asynchronous) 同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后, ...
- java高并发系列 - 第21天:java中的CAS操作,java并发的基石
这是java高并发系列第21篇文章. 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用ja ...
随机推荐
- ZT eoe android4.2 Bluetooth记录01-结构和代码分布
android4.2 Bluetooth记录01-结构和代码分布 作者:cnhua5更新于 08月21日访问(697)评论(2) 在android4.2中,Google更换了android的蓝牙协议栈 ...
- 【4】python函数基础
---恢复内容开始--- 案例1:时间下一秒程序 #__author:"吉勇佳" #date: 2018/10/14 0014 #function: timestr=input(& ...
- debug的粗略使用(求大神们补充、指教,小渣马上改)
debug的使用 往往我们在写代码的时候会发现那种很隐秘的bug,一直找找不多,甚至开始怀疑人生.目光扫描和人脑编译又耗时又耗精力又很容易中途乱了脑子,一切得重新来,所以我写了一篇博客来模拟一下检查b ...
- C++11 的右值引用
作者:Tinro链接:https://www.zhihu.com/question/22111546/answer/30801982来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- mysql5.7.22的安装与配置(适用mysql5.7.20至mysql5.7.22版本)
一.解压Mysql5.7.20安装包,刚解压是没有 data 这个文件夹的 二.配置mysql环境变量,创建MYSQL_HOME,然后在Path上添加%MYSQL_HOME%\bin; 三.配置m ...
- 处理Account locked due to 217 failed logins的问题
处理Account locked due to 217 failed logins的问题 [root@xxx1 ~]# scp 123.txt root@IP地址:/root Account lock ...
- React Native 基础报错及解决方案记录
刚开始上手RN,碰到很多坑,记录一下.碰到问题多去看看github上面的issue! 启动命令react-native run-ios报错 1.:xcrun: error: unable to fin ...
- Result工具类
使用ajax请求访问时,可以用此工具类作为返回对象,也方便统一代码规范 package com.ujia.entity; import java.io.Serializable; public cla ...
- FTP response 421 received. Server closed connection
现象: 在springboot的定时器轮询去下载ftp文件时,报以下错误: org.apache.commons.net.ftp.FTPConnectionClosedException: FTP r ...
- 1483. [HNOI2009]梦幻布丁【平衡树-splay】
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...