欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 并发编程---重排序

并发编程---重排序

2025/10/22 6:49:14 来源:https://blog.csdn.net/jlihan/article/details/145694054  浏览:    关键词:并发编程---重排序

文章目录

  • 什么是重排序?
    • 重排序的三种来源
  • 重排序的影响
    • 可见性问题
    • 有序性问题
  • 如何避免重排序带来的问题?
    • volatile关键字
    • synchronized 关键字
    • final关键字
    • happens-before规则


什么是重排序?

重排序是指在不改变程序最终执行结果的前提下,编译器、处理器或内存系统对指令的执行顺序进行重新排列,以提高程序的执行效率。

重排序的三种来源

  1. 编译器重排序
    • 编译器在生成字节码或机器码时,可能会对指令进行重新排序。
    • 例如:将不相关的指令提前或延后执行,以减少指令流水线的停顿。
  2. 处理器重排序
    • 现代处理器为了提高执行效率,可能会对指令进行乱序执行(Out-of-Order Execution)。
    • 例如:处理器可能会将没有数据依赖的指令并行执行。
  3. 内存系统重排序
    • 由于 CPU 缓存的存在,不同线程对内存的读写操作可能会被重新排序。
    • 例如:写操作可能会被延迟,而读操作可能会被提前。

重排序的影响

在单线程环境下,重排序不会影响程序的最终结果,因为编译器和处理器会保证程序的 串行语义(As-If-Serial)。但在多线程环境下,重排序可能会导致 可见性问题有序性问题,从而引发并发 Bug。

可见性问题

  • 由于重排序,一个线程对共享变量的修改可能对其他线程不可见。

例如:

int a = 0;
boolean flag = false;// 线程 1
a = 1;          // 操作 1
flag = true;    // 操作 2// 线程 2
if (flag) {     // 操作 3System.out.println(a);  // 操作 4
}
  • 由于重排序,操作 1 和操作 2 可能会被重新排序,导致线程 2 看到 flagtrue,但 a 仍然是 0

注意:两个线程是并发执行的,但并不是完全同时执行的。对于并发执行的线程,操作的顺序是不可预知的,而这正式引发重排序问题的原因

有序性问题

  • 由于重排序,程序的执行顺序可能与代码的编写顺序不一致。

例如:

int x = 0;
int y = 0;// 线程 1
x = 1;  // 操作 1
y = 2;  // 操作 2// 线程 2
if (y == 2) {  // 操作 3System.out.println(x);  // 操作 4
}
  • 由于重排序,操作 1 和操作 2 可能会被重新排序,导致线程 2 看到 y2,但 x 仍然是 0

如何避免重排序带来的问题?

为了避免重排序带来的并发问题,Java 提供了 内存屏障(Memory Barrier)同步机制 来保证程序的可见性和有序性。

volatile关键字

  • volatile 保证每次读取和写入共享变量时,都会直接访问主内存,而不是线程的本地缓存,因此它确保了变量在多个线程之间的 可见性

例如:

volatile boolean flag = false;
  • flag 被标记为 volatile 后,线程 A 对 flag 的修改会立即对线程 B 可见,不会存在缓存问题。

synchronized 关键字

  • synchronized 关键字通过加锁和解锁操作来保证代码块的原子性、可见性和有序性。

例如:

synchronized (lock) {a = 1;flag = true;
}

final关键字

  • final 关键字可以禁止构造函数中的指令重排序,确保对象的正确初始化。

例如:

final int x;
x = 10;  // 构造函数中的赋值操作不会被重排序

happens-before规则

  • Java 内存模型(JMM)定义了一系列 happens-before 规则,用于描述操作之间的可见性和有序性。
  • 例如:
    • 单线程规则:在同一个线程中,前面的操作 happens-before 后面的操作。
    • volatile 规则:对 volatile 变量的写操作 happens-before 后续对它的读操作。
    • 锁规则:解锁操作 happens-before 后续的加锁操作。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词