JAVA并发-什么是指令重排?

1.什么是指令重排

        指令重排是计算机编译器或处理器为了提高性能而对指令执行顺序进行的一种优化手段。在多核和多线程的计算机系统中,指令重排的目标是通过优化执行顺序来提高指令级别的并行度,充分发挥计算资源,加速程序的执行。

2.指令重排的原理

2.1 数据依赖性:

        在指令重排时,编译器和处理器会尽量保留程序的语义,即确保不会改变程序的原始语义。这就要求在进行重排时要考虑数据的依赖关系,保证对于具有依赖关系的指令不会改变其执行顺序。

2.2 重排序的类型:

        指令重排主要包括编译器重排处理器重排两种类型。编译器重排指的是编译器在生成目标代码时进行的优化,而处理器重排则是指在指令执行阶段,由于处理器的乱序执行机制,实际执行的顺序可能与源代码中的顺序不同。

3.指令重排的影响

3.1 内存屏障

        内存屏障(Memory Barrier)是一个CPU指令,用于禁止特定类型的指令重排。volatile关键字和synchronized块都会引入内存屏障,确保在其前后的指令不会发生重排。

        原理:

                由于编译器和处理器都能执行指令重排优化。如果在指令间插入一条内存屏障则会告诉编译器和CPU,不管什么指令都不能和这条内存屏障指令重排,也就是说通过插入内存屏障,就能禁止在内存屏障前后的指令执行重排优化。内存屏障另外一个作用就是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。【volatile体现】

3.2 多线程同步问题

        在没有适当同步的情况下,一个线程在写入共享变量后,其它线程可能读到一个尚未完成初始化的对象,导致不一致的状态。

        例如:

// 线程1
instance = new SomeObject(); // 1
ready = true; // 2

// 线程2
if (ready) {
    // 可能读到尚未完成初始化的 instance
    use(instance);
}

        在上述例子中,由于指令重排,线程2可能在检测到readytrue时读取到尚未完成初始化的instance

3.参考

【面试问题】什么是指令重排?-阿里云开发者社区

java volatile禁止指令重排_volatile禁止指令重排的原理-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值