文档章节

为什么volatile能保证可见性?

Hosee
 Hosee
发布于 2016/08/14 12:30
字数 693
阅读 680
收藏 5
点赞 0
评论 0

我们都知道volatile能保证可见性,不能保证原子性,比如i++操作

也知道Happen-Before原则,那么是如何确保Happen-Before原则不被指令重排序影响呢?(如果对上述描述有困惑请移步[高并发Java 三] Java内存模型和线程安全

例如你让一个volatile的integer自增(i++),其实要分成3步:1)读取volatile变量值到local; 2)增加变量的值;3)把local的值写回,让其它的线程可见。这3步的jvm指令为:

mov   
0xc(%r10),%r8d
 ; Load
inc   
 %r8d           ; Increment
mov   
 %r8d,0xc(%r10)
 ; Store
lock
 addl $0x0,(%rsp)
 ; StoreLoad Barrier

StoreLoad Barrier就是内存屏障

内存屏障(memory barrier)是一个CPU指令。基本上,它是这样一条指令: a) 确保一些特定操作执行的顺序; b) 影响一些数据的可见性(可能是某些指令执行后的结果)。编译器和CPU可以在保证输出结果一样的情况下对指令重排序,使性能得到优化。插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。内存屏障另一个作用是强制更新一次不同CPU的缓存。例如,一个写屏障会把这个屏障前写入的数据刷新到缓存,这样任何试图读取该数据的线程将得到最新值,而不用考虑到底是被哪个cpu核心或者哪颗CPU执行的。

内存屏障和volatile什么关系?上面的虚拟机指令里面有提到,如果你的字段是volatile,Java内存模型将在写操作后插入一个写屏障指令,在读操作前插入一个读屏障指令。这意味着如果你对一个volatile字段进行写操作,你必须知道:1、一旦你完成写入,任何访问这个字段的线程将会得到最新的值。2、在你写入前,会保证所有之前发生的事已经发生,并且任何更新过的数据值也是可见的,因为内存屏障会把之前的写入值都刷新到缓存。 

明白了内存屏障这个CPU指令,回到前面的JVM指令:从Load到store到内存屏障,一共4步,其中最后一步jvm让这个最新的变量的值在所有线程可见,也就是最后一步让所有的CPU内核都获得了最新的值,但中间的几步(从Load到Store)是不安全的,中间如果其他的CPU修改了值将会丢失。

所以volatile不能保证i++操作的原子性

本文转载自:http://blog.csdn.net/hupitao/article/details/45227891

共有 人打赏支持
Hosee
粉丝 524
博文 132
码字总数 207228
作品 0
杭州
程序员
原子变量、volatile、synchronized的可见性和原子性比较

jdk5提供了java.util.concurrent包,这个包并行功能强大,工具齐全,其中就包括原子变量atomic 那么我们先说说volatile,volatile可以保证内存的可见性,禁用重排序,但是不能保证操作的原子性...

AI9o後
2017/11/03
0
0
关于Java变量的可见性问题

关于Java变量的可见性问题 博文前提 最近在oschina问答板块看到了一个关于java变量在工作内存和主存中的可见性问题:synchorized,sleep 也能达到volatile 线程可见性的目的?,大致的问题描述如...

Ambitor
2016/04/18
410
13
java并发编程-volatile内存实现和原理

前面的博文说了java的内存模型,介绍了java内存模型的基础,此篇文章来说一下volatile关键字,这个在并发编程中,占有举足轻重地位的关键字。 在java5.0 之前它是一个备受争议的关键字,5之后它重...

GordonNemo
03/14
0
0
java并发编程系列-volatile内存实现和原理

前面的博文说了java的内存模型,介绍了java内存模型的基础,此篇文章来说一下volatile关键字,这个在并发编程占有举足轻重地位的关键字。在java5.0 之前它是一个备受争议的关键字,5之后它重获新...

起个名忒难
2017/11/19
0
0
轻量级的同步机制——volatile语义详解(可见性保证+禁止指令重排)

1.关于volatile volatile是java语言中的关键字,用来修饰会被多线程访问的共享变量,是JVM提供的轻量级的同步机制,相比同步代码块或者重入锁有更好的性能。它主要有两重语义,一是保证多个线程...

takumiCX
07/12
0
0
线程安全到底是什么意思?

本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数据库事务的原子性概念差不多,即一个操作(有可能包含有多个...

李矮矮
2016/10/17
89
0
并发和多线程-说说面试常考平时少用的volatile

说到volatile,一些参加过面试的同学对此肯定不陌生。 它是面试官口中的常客,但是平时的编码却很少打照面(起码,我是这样的)。 最近的面试,我也经常会问到volatile相关的问题,比如volat...

Jackie_Zheng
06/02
0
0
Java 多线程:关键字 synchronized 和 volatile

关键字volatile是线程同步的轻量级实现,所以volatile性能比synchronized要好,volatile智能修饰变量,而synchronized可以修饰方法以及代码块。随着JDK新版发布,synchronized关键字在执行效...

JianF
2016/12/16
16
0
java并发编程 - volatile

一、 volatile基本介绍 Java 语言提供了一种稍弱的同步机制,即 volatile 变量.用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新. 当把...

YuanyuanL
2015/08/11
0
0
Java并发学习(七)-AtomicInteger基本数据类型类

从Java5开始,出现了concurrent并发包,这里主要先介绍atomic包下面的AtomicXXX诸如AtomicBoolean,AtomicInteger,AtomicLong等原子更新类,它们内部实现思想基本一致,这里以AtomicInteger...

anLA_
2017/11/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

PostgresSQL 查看当前schema下所有的函数/存储过程

selectroutine_name from information_schema.routineswhere routine_catalog = 'YourDBName'and routine_schema = 'YourSchemaName'order by routine_name;...

Leyxiao
2分钟前
0
0
去除bootstrapValidator 的校验结果

$("#form").data('bootstrapValidator').destroy();//会报没有这个方法,很奇怪 $('#form').data('bootstrapValidator',null); $('#form').bootstrapValidator();...

暗中观察
4分钟前
0
0
java环境安装

1、首先下载jdk安装包,一般去官网,官网需要登录才可以下载。 2、下载完成双击运行,想改路径改下路径,比较简单。安装jdk安装完,会弹出个窗口,提示开始安装jre的位置,我这里窗口比较奇葩...

朝如青丝暮成雪
5分钟前
0
0
Linux Command

Copy with progress rsync -r --progress source dest

Lyle_W
6分钟前
0
0
个灯数据营销,帮你找回被浪费的广告费

近日,个灯受邀出席被喻为广告营销业界的年度盛会——第八届梅花网传播业大展北京站的活动。 在展会上,个灯总经理严雯婷女士带来了《数据增能,营销智能》的主题演讲,以理论与实践相结合的...

个推
8分钟前
0
0
java的反射机制理解

一、概念说明 java的反射机制,是在运行状态下,可以动态获取任意一个类的属性和方法;可以动态调用一个对象任意方法; 二、反射相关类 java.lang.Class; //类 java.lang.re...

盼望明天
12分钟前
0
0
nginx反向代理-多端口映射

代码解释 1.1 http:www.baidu.test.com默认是80,访问“/”利用反向代理,然后访问本地8083; 1.2 8083代表本地的前端工程访问地址,前端需要访问后台数据,”/”,继续代理到后台地址9803; ...

lilugirl
13分钟前
0
0
Jfinal使用log4j2打印日志

1,添加maven配置 <properties><log4j2.version>2.11.0</log4j2.version><slf4j.version>1.7.25</slf4j.version></properties> <!--slf4j及log4j2日志 --><dependency> ......

iborder
14分钟前
0
0
如何在Rancher 2.0上快速部署Datadog

Datadog是一种流行的托管监控解决方案,用于聚合和分析分布式系统的指标和事件。从基础架构集成到协作仪表板,Datadog为用户提供了一个简洁的单一窗格视图,用户可以快速查看对其最重要的信息...

RancherLabs
17分钟前
0
0
Java示例演示Functor 和monad

This article was initially an appendix in our Reactive Programming with RxJavabook. However introduction to monads, albeit very much related to reactive programming, didn't suit......

Quan全
35分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部