并发理论基础:指令重排序问题

95 篇文章 3 订阅 ¥9.90 ¥99.00
15 篇文章 0 订阅
本文介绍了指令重排的目的和原则,强调在不改变单线程语义的情况下允许重排以优化性能。同时,讨论了重排在多线程环境下可能导致的问题,通过例子展示了如何引发线程安全问题。最后,提到了如何通过内存屏障和Java的Volatile、synchronized、final关键字来禁止重排序,确保并发安全。
摘要由CSDN通过智能技术生成

目录

一、学习总结

二、参考资料


一、学习总结

  • 1、指令重排(编译器、处理器重排)

 目的就是把CPU的资源利用起来,这样就能就能提升整个计计算机的效率,性能优化。
 重排的原则:在不改变单线程语义情况下(即不改变单线程执行程序的结果,也就是程序结果不会改变),允许对程序执行顺序重排。 即遵循as-if-serial。
 同一个方法中,没有语句依赖关系的程序,执行顺序可能会被重排
     a=1;  //1
     b=2;  //2
     c=a+1; //3   
因位b=2;没有上下文依赖,因此编译器优化后可能执行顺序如下:

     b=2;   //2
     a=1;   //1
     c=a+1; //3   
     

  • 2、重排序对多线程的影响     

    例如两个线程分别调用下面的两个方法,调用getValue()方法的线程,输出的value可能为0。因位在init方法中,可能会先执行flag=true; ,然后再执行,value=8;
      private static int value;
     private static boolean flag;
 ​
     public static  void  init(){
         value=8;     //语句1
         flag=true;  //语句2
     }
 ​
     public static void getValue(){
         if(flag){
             System.out.println(value);
         }
     }

 

  • 3、禁止重排序

    编译器无法根据语义来知道代码指令的依赖关系,因此需要人显示的告诉编译器,某个地方禁止指令重排。
    在cpu和编译器层面都提供了一套内存屏障,来禁止重排指令。JAVA内存模型JMM把这些负责的给封装后简单化了。
    程序员可以通过Volatile、synchronized、final几个关键字告诉编译器和处理器哪些地方是不允许进行重排序的。
    

  • 4、总结:

    [1]为什么要进行指令重排(提高cpu利用率、提高性能)
    [2]三种指令重排的场景(编译器、指令集并行的重排、内存重排)
    [3]指令重排原则(as-if-serial)
    [4]单线程重排、多线程重排、禁止重排

 


二、参考资料

https://zhuanlan.zhihu.com/p/298448987

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值