指令重排序代码演示

概念

指令重排序,顾名思义,就是对指令的执行顺序重新进行排序。

编译器编译时重排序问题

编译器在编译代码时,不会等待阻塞指令完成,而是先去编译执行其他指令,目的和处理器执行时乱序优化一样,但是效果你上更好,它可以完成更大范围、效果更好的指令乱序优化。

处理器执行时乱序优化

乱序优化,实际上也遵循着一定规则:只要两个指令之间不存在数据依赖,就可以对这两个指令乱序。不必关心数据依赖的精确定义,可以理解为:只要不影响程序单线程、顺序执行的结果,就可以对两个指令重排序。
处理器乱序优化节省了大量的等待时间,提高了处理器的性能。
如果是单核情况下,乱序优化完全没有问题,因为它保证了单线程的执行结果不变。但是在多核时代的多线程并行情况下,不同线程之间共享了数据,就会出现问题

举个栗子

package com.coderman.jmm;

import java.util.concurrent.CountDownLatch;

/**
 * 演示重排序
 * 1. a=1;x=b;b=1;y=a; ==> a=1;x=0;b=1;y=1; (x=0,y=1)
 * 2. b=1;y=a;a=1;x=b; ==> b=1;y=0;a=1;x=1; (x=1;y=1)
 * 3. a=1;b=1;x=b;y=a; ==> a=1;b=1;x=1;y=1; (x=1;y=1)
 * 4. x=b;b=1;y=a;a=1; ==> x=0;b=1;y=0;a=1; (x=0;y=0) 发生重排序,在一个线程中指令的顺序发生颠倒,JIT编译器的优化
 *
 * @Author zhangyukang
 * @Date 2020/6/30 14:08
 * @Version 1.0
 **/
public class OutOfOrderExecution {
    private static int x=0,y=0;
    private static int a=0,b=0;

    private static int count=0;

    public static void main(String[] args) throws InterruptedException {

        while (true){
            count++;
            x=0;
            y=0;
            a=0;
            b=0;
            CountDownLatch countDownLatch=new CountDownLatch(1);
            Thread one = new Thread(() -> {
                a = 1;
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                x = b;
            });

            Thread two = new Thread(() -> {
                b = 1;
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                y = a;
            });

            one.start();
            two.start();
            countDownLatch.countDown();
            one.join();
            two.join();

            if (x == 0 && y == 0) {
                System.out.println("第"+count+"次结果"+"x="+x+",y="+y);//说明发生了重排序
                break;
            } else {
                System.out.println("第"+count+"次结果"+"x="+x+",y="+y);
            }
        }

    }
}

第245438次结果x=0,y=1
第245439次结果x=1,y=0
第245440次结果x=0,y=1
第245441次结果x=0,y=1
第245442次结果x=0,y=0 //发生了指令重排序

评论

公众号:mumuser

企鹅群:932154986

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×