JMM内存模型重排序1、重排序 2.as-if-serial语义 3.程序顺序规则

一、重排原因:

为了提升代码的运行效率,所以编译器和处理器会对代码的执行顺序进行重新排序,但是有单处理器上和单线程上的数据依赖的一定不会重新排序,但是不同处理器和不同线程上的不考虑

二、as-if-serial :

as-if-serial的意思就是,无论如何重排,单线程都不会改变最终的执行结果

如何做到:

为了as-if-serial的实现,所以对有数据依赖的数据不进行重排,因为这种重排会改变结果。但是如果不存在数据依赖,那么就可能会被重排。如下图

A和B直接没有数据依赖所以他们顺序改变不会对结果改变,但是A和C他们有数据依赖所以顺序可以是A->B->C 或者B->A->C

as-if-serial结果:

as-if-serial对于单线程来说,就相当于遵守as-if-serail语义的处理器、编译器、runtime,为我们提供了一种假象,那么就是单线程下,指令是按照顺序执行的,但在单线程下,如果存在数据依赖那么一定不重排,但是不存在可以重排,因为如果不存在也不会对结果有影响。这样就不用担心内存可见性了。

三、程序顺序规则

通过上面计算圆面积我们知道,他们happens-before如下

A-happens-beforeB

B-happens-beforeC

A-happens-beforeC

这里Ahappens-beforeB但是B也可以在A以前执行,但是B执行要对A保持可见,

在计算机的世界里,我们遵循一个规则那就是,在不改变结果的情况下,最大程度提高并行度,可以进行重排来提高运行速度。从JMM来看他也遵守这样的规则。
 

四、重排序对多线程的影响

如果俩个线程A和B同时分别执行writer和reader方法,那么会按照我们期盼的1234这样执行吗,答案是不会,

如果reader中的12和重排因为他们两个没有数据依赖,

如图3-8所示,操作1和操作2做了重排序。程序执行时,线程A首先写标记变量flag,随后线 程B读这个变量。由于条件判断为真,线程B将读取变量a。此时,变量a还没有被线程A写入,在 这里多线程程序的语义被重排序破坏了!

如果三和4发生重排会发生啥

如果3和4重排,因为他们存在控制依赖,所以编译器和处理器会采用猜测的方式就是提前,去计算a*a的值,当flag为true执行,但是如果这中间a的值在一次发生改变,那么3和4的指令重排就会破坏语义。

在单线程程序中,对存在控制依赖的操作重排序,不会改变执行结果(这也是as-if-serial 语义允许对存在控制依赖的操作做重排序的原因);但在多线程程序中,对存在控制依赖的操 作重排序,可能会改变程序的执行结果。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值