JMM重排序

先看一个简单问题

定义了A=0,B=0;a=0,b=0四个全局变量。设计两个线程,线程1执行a=1;A=b;    线程2执行b=1;B=a;

要求一:两个线程遵循Happens-Before原则

要求二:保证两个线程都执行完后打印出A的值,B的值(注:列举出A,B的所有可能的取值组合,并解释每一种组合发生的原因)

答案:

第一种: A=0,B=1  thread1在thread2之前先执行(a=1,A=0; b=1,B=1)

第二种:   A=1,B=0  thread2在thread1之前先执行(b=1,B=0; a=1,A=1)

第三种:   A=1,B=1  thread1在thread2同时执行 (a=1,b=1; A=1,B=1) //这里可以使用 CountDownLatch来尽可能保证线程1的a=1;和线程2的b=1同时执行;

第四种:  A=0,B=0  发生这种情况的原因只有一个,那就是线程一和线程二的代码的执行顺序发生了改变:

B=a

a=1

A=b

b=1

我们可以看出其实是线程2的代码的执行顺序发生了改变才会出现第四种情况,这就是所谓的重排序

 再看代码:

public class ReorderingCode {


    private static int A=0,B=0;// 这里其实可以用volatile来解决第四种情况的发生
    private static int a=0,b=0;
    public static void main(String[] args) throws InterruptedException {
         CountDownLatch lunch=new CountDownLatch(1);
         int sum=0;
            for (;;){
                A=0;B=0;a=0;b=0;
                sum++;
                Thread thread1 = new Thread(new Runnable()  {
                    @Override
                    public void run() {
                        try {
                            lunch.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        a=1;
                        A=b;
                    }
                });
                Thread thread2 = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            lunch.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        b=1;
                        B=a;
                    }
                });
                thread1.start();
                thread2.start();
                lunch.countDown();
                thread1.join();
                thread2.join();
                if (A==0&&B==0){
                    System.out.println("执行了"+sum+"次"+"A="+A+","+"B="+B);
                    break;
                };
            }

         }

}

 结论:

前三种情况出现是很正常的,但是第四种出现就不正常了,因为cpu剥夺了我们程序员的权利,它私自对我们代码的执行顺序做了调换,这就叫做重排序,但是这只是cpu层面的重排序我们可以看下图

从图中看重排序,我们便一目了然,但是发生重排序其实是很有好处的,但是我们在业务开发中一定要处理好这种情况发生的时候该怎么办来规避可能在生产中发生。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值