大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
volatile禁止指令重排
JMM要求有序性
计算机在执行程序时,为了提高性能,编译器和处理器常常会做指令重排,一把分为以下3种
单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致.(单线程不用关心指令重排)
处理器在进行重新排序是必须要考虑指令之间的数据依赖性
多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程使用的变量能否保持一致性是无法确定的,结果无法预测
源码写的顺序不见得和编译的指令顺序一样
例子1
比如源码如下
public void mySort(){
int x=11;//语句1
int y=12;//语句2
x=x+5;//语句3
y=x*x;//语句4
}
但是其中编译后的指令顺序可能为:
1234
2134
1324
问题:
请问语句4 可以重排后变成第一条码?
答:存在数据的依赖性 ,语句4 没办法排到第一个
正常情况下指令不重排,不是每次指令都会重排
例子2
int a ,b ,x,y=0;
线程1 线程2
x=a; y=b;
b=1; a=2;
结果 :x=0 y=0
如果编译器对这段代码进行执行重排优化后,可能出现下列情况:
线程1 线程2
b=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:学习笔记,资源:尚硅谷,周阳
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180767.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...