博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Volatile-3.禁止指令重排
阅读量:4035 次
发布时间:2019-05-24

本文共 900 字,大约阅读时间需要 3 分钟。

volatile禁止指令重排

JMM要求有序性

计算机在执行程序时,为了提高性能,编译器和处理器常常会做指令重排,一把分为以下3种

在这里插入图片描述

单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致.(单线程不用关心指令重排)

处理器在进行重新排序是必须要考虑指令之间的数据依赖性

多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程使用的变量能否保持一致性是无法确定的,结果无法预测

源码写的顺序不见得和编译的指令顺序一样

例子1

比如源码如下

public void mySort(){
int x=11;//语句1 int y=12;//语句2 x=x+5;//语句3 y=x*x;//语句4}

但是其中编译后的指令顺序可能为:

123421341324

问题:

请问语句4 可以重排后变成第一条码?
答:存在数据的依赖性 ,语句4 没办法排到第一个

正常情况下指令不重排,不是每次指令都会重排

例子2
int a ,b ,x,y=0;线程1	线程2x=a;	y=b;b=1;	a=2;结果 :x=0 y=0	如果编译器对这段代码进行执行重排优化后,可能出现下列情况:线程1	线程2b=1;	a=2;x=a;	y=b;	结果:  x=2 y=1	 这也就说明在多线程环境下,由于编译器优化重排的存在,两个线程使用的变量能否保持一致是无法确定的.
例子3

在这里插入图片描述

两个线程分别执行method1 和method2

多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程使用的变量能否保持一致性是无法确定的,结果无法预测

假设线程1首先执行method1:

默认是:

a=1;flag=true;

因为a与flag不存在数据依赖性,很可能出现指令重排,

flag=true;a=1;

在这种情况下,若执行完flag=true就被线程2抢走cpu执行method2,执行了if条件体内的命令,a成为5 就会和不指令重排的结果(6)不一致。

所以指令重排会造成值不一致,所以有时候我们需要 volatile禁止指令指令重排

总结(了解)

在这里插入图片描述

在这里插入图片描述

PS:学习笔记,资源:尚硅谷,周阳

转载地址:http://tvfdi.baihongyu.com/

你可能感兴趣的文章
如此调用
查看>>
计算机的发展史
查看>>
带WiringPi库的交叉编译如何处理一
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Spring事务的七种传播行为
查看>>
ES写入找不到主节点问题排查
查看>>
Java8 HashMap集合解析
查看>>
ArrayList集合解析
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
Android计算器实现源码分析
查看>>
Android系统构架
查看>>
Android 跨应用程序访问窗口知识点总结
查看>>
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
js弹窗插件
查看>>
自定义 select 下拉框 多选插件
查看>>
js判断数组内是否有重复值
查看>>
js获取url链接携带的参数值
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>