java并发之重排序问题

1.重排序的类型

行程序了提高性能,编译器和理器常常会指令做重排序。重排序分3类型。
1编译化的重排序编译器在不改变单线程程序语义的前提下,可以重新安排句的执序。
2指令并行的重排序理器采用了指令并行技Instruction-Level Parallelism,ILP)来将多条指令重叠行。如果不存在数据依性,理器可以改变语对应机器指令的执序。
3内存系的重排序。由于理器使用存和/冲区,使得加和存操作看上去可能是在乱序执行。

2.如何在重排序之后减少可见性问题

        这些重排序可能会致多线程程序出现内存可问题编译器,JMM编译器重排序规则会禁止特定型的编译器重排序(不是所有的编译器重排序都要禁止)。
        对理器重排序,JMM理器重排序规则会要求Java编译器在生成指令序列,插入特定型的内存屏障(Memory BarriersIntel称之为Memory Fence)指令,通内存屏障指令来禁止特定型的理器重排序。

3.数据依赖性

        如果两个操作访问同一个量,且两个操作中有一个写操作,此时这两个操作之间就存在数据依赖性。
上面3种情况,只要重排序两个操作的序,程序的果就会被改
        前面提到过编译器和理器可能会操作做重排序。编译器和理器在重排序,会遵
守数据依性,编译器和理器不会改存在数据依关系的两个操作的序。这里所的数据依仅针对单理器中行的指令序列和线程中行的操作,不同处理器之和不同线程之的数据依性不被编译器和理器考

4.as-if-serial语义

as-if-serial语义是保证不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。
        A和C存在数据依关系,同BC也存在数据依关系。因此在最终执行的指令序列中,C不能被重排序到AB的前面(C排到AB的前面,程序的果将会被改变)。但AB没有数据依关系,编译器和理器可以重排序AB序。
        as-if-serial语义单线程程序保了起来,遵守as-if-serial语义编译器、runtime理器共同为编单线程程序的程序员创建了一个幻单线程程序是按程序的序来行的。as-if-serial语义使单线程程序无需担心重排序会干,也无需担心内存可问题

5.程序排序规则

根据happens-before的程序规则,上面的面的示例代存在3happens
before关系。
1A happens-before B
2B happens-before C
3A happens-before C
        这里的第3happens-before关系,是根据happens-before传递性推出来的。这里A happens-before B,但实际执B却可以排在A之前行(看上面的重排序后的执行顺序)。如果A happens-before BJMM并不要求A一定要在B之前行。JMM仅仅要求前一个操作(执行的果)后一个操作可,且前一个操作按序排在第二个操作之前。里操作A的执果不需要操作B;而且重排序操作A和操作B后的果,与操作A和操作B按happens-before行的果一致。在种情况下,JMM认为这种重排序并不非法(not illegal),JMM许这种重排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值