volatile有序性的真正作用
中心思想
使普通全局变量的写对其他线程立即可见(使用volatile有序性来传递)
内存屏障
先来一堆有必要的废话
- LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
- StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
- LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
- StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。
Java内存模型允许编译器和处理器对指令重排序以提高运行性能,并且只会对不存在数据依赖性的指令重排序。
为了实现volatile的有序性内存语义(jdk5之后),编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
- 在每个volatile写操作的前面插入一个StoreStore屏障。
- 在每个volatile写操作的后面插入一个StoreLoad屏障。
- 在每个volatile读操作的前面插入一个LoadLoad屏障。
- 在每个volatile读操作的后面插入一个LoadStore屏障
volatile写操作插入内存屏障后生成的指令序列如下图所示。
volatile读操作插入内存屏障后生成的指令序列如下图所示。
传递性 :如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
相信大家对上面的内容很熟悉了,但是代表啥意思呢,估计你还是一头雾水。我们举个例子
int e = 0;
volatile f = 0;//thread 1
e = 1; //操作 A
f = 1; //操作 B//thread 2int j = f; //操作 C
int k = e; //操作 D
我们假设 thread 1 执行结束之后thread 2执行,由于f是volatile变量,那么可知B操作的写,对于C操作的读是可见的。那么可得B先发生与C,每个线程单独来看, A先发生与B, C先发生与D,最后我们再加上传递性可知。
A->B->C->D
至此我们可以得到普通变量e的的写入对于其他线程立即可见(注意变量f在其中起到的作用)
Reentrantlock 也借助了volatile的这个特性
总结一下有序性的含义
- 禁止指令重排
- volatile写会将线程工作缓存(cpu缓存)中的所有数据写入主存
- volatile读会将线程工作缓存(cpu缓存)中的所有数据失效,读的时候需要从主存中取。
测试代码
前面举的例子比较难测试出反例(对普通变量的写,不通过volatile的有序性保证,其他线程不是立即可见),所以写了下面的测试代码。
static int a = 0;static volatile int b = 0; //去掉volatile修饰会发生死循环,即变量a对于其他线程不是立即可见public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while(a==0) {int c = b;}});thread.start();Thread.sleep(200);new Thread(() -> {a = 1;b = 1;}).start();thread.join();}
volatile有序性的真正作用相关推荐
- C语言 const、static、volatile等关键字的作用
目录 前言 const static volatile extern 总结 前言 C语言里面有许多关键字,本文结合我自己的了解简单讲讲几个常用关键字的作用. const 问:const有什么用? 答: ...
- volatile是怎么保证可见性和有序性的,为什么无法保证原子性
文章目录 1. JMM内存模型 2. 并发编程的三大特性 3. Volatile的原理分析 在了解volatile之前,先认识一下JMM内存模型和并发编程的三大特性! 1. JMM内存模型 Java内 ...
- Java中volatile的作用以及用法
volatile让变量每次在使用的时候,都从主存中取.而不是从各个线程的"工作内存". volatile具有synchronized关键字的"可见性",但是没有 ...
- java中关键字volatile的作用(转载)
转载:http://blog.csdn.net/orzorz/article/details/4319055 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对 ...
- java 关键字volatile的作用
用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...
- (免费领取名企Java面试题)volatile作用,指令重排相关
(免费领取名企Java面试题)volatile作用,指令重排相关 Java是当下最热门的编程语言,越来越多的年轻人开始从事Java方面的工作,高就业率,高薪水的岗位,是吸引他们的原因.每个行业都有三六 ...
- volatile作用
volatile 的主要作用有两点: - 保证变量的内存可见性 - 禁止指令重排序 前提知识了解 JMM 所有的共享变量都存储于主内存.这里所说的变量指的是实例变量和类变量,不包含局部变量,因为局部变 ...
- 对volatile的理解
JMM 是什么 JMM(java内存模型 Java Memory Model)本身是一种抽象的概念,描述一组规则后规范通过这组规范定义了程序中各个变量(包括实例字段,静态变量和组成数组对象的元素)的访 ...
- 【并发编程】volatile简单使用
Atomic 以更为轻量的方式实现原子性..本次我们学习 volatile 关键字,则是用来解决可见性.有序性问题. 简介 在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变 ...
- null在java存在的意义何在,Java并发编程——volatile关键字
一.volatile是什么 volatile是Java并发编程中重要的一个关键字,被比喻为"轻量级的synchronized",与synchronized不同的是,volatile ...
最新文章
- 【转】matlab函数_连通区域
- 跳出数据计算拯救人工智能之分布式逻辑
- php 写入文件 格式,在使用php写入文件时如何保证用户的单一
- winform list集合怎么 in过滤_python3基础04字典(dict)和集合(set)
- int类型存小数 mysql_MySQL面试题-数据类型
- javascript 解密_Javascript中的AES加密和Java中的解密
- Oracle-1 / Oracle及PlsqlDeveloper的设置
- 导弹如何自动追踪目标?这其实是个数学问题
- 【Java从0到架构师】SpringMVC - RESTful
- linux多媒体功能,Ubuntu 8.04中文强化版 多媒体功能更强大
- 适合有基础的Java实战项目——坦克大战 练手实战项目
- 【图像分割】基于粒子群算法实现图像聚类分割附matlab代码
- vue调用企业微信API详细过程
- 镭神C16上位机软件显示
- CHECK约束在表继承中的使用
- 使用poi解析Excel
- 企业私有网络构建与运维
- excel数据透视表数据排序及excel表格转成word表
- 【有利可图网】设计配色方案之紫色系篇
- 使用 Vuex + Vue.js 构建单页应用