多线程中的指令重排序问题

java并发编程中的重排序问题

重排序

在多核处理器的环境下,编写的顺序结构,这种操作执行的顺序可能是没有保障的:

编译器、处理器可能会改变两个操作的先后顺序

这种一个处理器上执行的多个操作,在其他处理器来看它的顺序与目标代码指定的顺序可能是不一样的,这种现象称为重排序。

重排序是对内存访问有序操作的一种优化,可以在不影响单线程程序正确的情况下提升程序的性能,但是,可能对多线程程序的正确性产生影响,即可能产生线程安全问题。

重排序与可见性问题类似,不是必然出现的,与内存操作顺序有关的几个概念:

  1. 源代码执行顺序:就是源码中指定的内存访问顺序
  2. 程序顺序:处理器上运行的目标代码所指定的内存访问顺序
  3. 执行顺序:内存访问操作在处理器上的实际执行顺序
  4. 感知顺序:给定处理器所感知到的该处理器及其他处理器的内存访问操作顺序

可以把重排序分为指令重排序与存储子系统重排序两种,指令重排序和存储子系统重排序。指令重排序主要是由编译器、处理器引起的,指程序顺序与执行顺序不一样。存储子系统重排序是由高速缓存,写缓存器引起的,感知顺序与执行顺序不一致。

指令重排序

在源码顺序与程序不一致或者程序顺序与执行顺序不一致的情况下,我们就说发生了指令重排序。

指令重排序是一种动作,确实对指令的顺序做了调整,重排序的对象指令,javac编译器一般不会执行指令重排序,而JIT编译器可能执行指令编译器,处理器也可能执行指令重排序,使得执行顺序和程序顺序不一致,指令重排序不会对单线程的程序结果产生影响(因为编译器和处理器不会改变存在数据依赖的两个操作的顺序),可能导致多线程出现非预期的结果。

存储子系统重排序

存储子系统是指缓冲器和高速缓存,高速缓存(Cache)是CPU中为了匹配与主内存处理速度不匹配而设计的一个高速缓存写缓冲器用来提高些高速缓存操作的效率。

即使处理器严格按照程序执行顺序执行两个内存访问操作,在存储子系统的作用下,其他处理器对这两个操作的感知顺序与程序顺序不一致,即这两个操作的顺序看起来是发生了变化,这种现象称之为存储子系统重排序。

存储子系统重排序并没有真正的对指令执行顺序进行调整,而是造成一种指令执行顺序被调整的现象,存储子系统重排序对象是内存操作的结果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值