volatile禁止指令重排序_volatile int

volatile禁止指令重排序_volatile intvolatile 禁止指令重排 JMM 要求有序性 计算机在执行程序时 为了提高性能 编译器和处理器常常会做指令重排 一把分为以下 3 种 单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致 单线程不用关心指令重排 处理器在进行重新排序是必须要考虑指令之间的数据依赖性 多线程环境中线程交替执行 由于编译器优化重排的存在 两个线程使用的变量能否保持一致性是无法确定的 结果无法预测

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:学习笔记,资源:尚硅谷,周阳

编程小号
上一篇 2025-01-19 23:57
下一篇 2025-01-19 23:46

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/148095.html