Volatile-3.禁止指令重排

博客探讨了在多线程环境下,volatile关键字如何保证变量的可见性和禁止指令重排,以确保线程间的同步。通过3个例子展示了在没有volatile的情况下,指令重排可能导致的不一致性问题,强调了volatile在保持数据一致性和有序性方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值