目录

「003」 Java 指令重排序

目录

重排序的内容:编译器和处理器对指令重新排序,以新的顺序执行指令

重排序的目的:提升执行程序的性能,尽可能利用处理器的并行能力

重排序的过程:Java 有三重重排序机制。编译器首先在不改变单线程程序语义的前提下,重新安排指令顺序,这一重叫做编译器优化的重排序。采用了指令集并行技术的多核处理器可以重叠执行多条指令,在不存在数据依赖性的情况下,处理器可以改变指令的执行顺序,这一重叫做指令级并行的重排序。在对数据进行读写的过程中,由于多核处理器采取了缓冲区技术,每个变量的读写都需要经过寄存器-缓存-内存三步,这导致各个处理器的 load 和 save 操作看上去是乱序的,这一重叫做内存系统的重排序

1
2
3
graph LR;
	源代码 --> 编译器优化的重排序 --> 指令级并行的重排序 --> 内存系统的重排序 --> 最终执行序列

线程不安全的现象是处理器系统三级缓存机制和多处理器系统共同作用下产生的。

首先三级缓存导致了,处理器中对变量的修改无法及时反映到内存中,其次多处理器系统每个处理器都有各自的缓存,CPU1 和 CPU2 同时读取数据块 A 加载进各自的缓存,当 CPU1 对数据块 A 修改后,结果 A‘ 保存在 Cache1 中,同时 CPU2 对数据块 A 也进行了修改,结果 A’’ 保存在 Cache2 中,很明显 A’ 和 A’‘ 未必一致,在写回这个过程中,可能产生冲突,从而导致线程不安全。

https://leslie-cloud.oss-cn-beijing.aliyuncs.com/2021/03/77292df7ebd1.png

缓存一致性问题:在多处理器系统中,每个每个处理器都有自己的高速缓存,但他们共享同一组内存,当多个处理器的运算任务都涉及到同一个块主内存区域时,将可能导致各自的缓存数据不一致。

^15cbcf