CPU 指令重排序

一、CPU 指令重排序

CPU 在运行时,为了提高运行效率会对指令进行重排序,以适应 CPU 的运行。CPU 指令重排序会遵循 as-if-serial 和 happens-before 原则。

① as-if-serial 语义:单个线程的执行结果不会发生改变。

② happens-before 语义:正确同步的多线程的执行结果不会发生改变。

as-if-serial 和 happens-before 原则,都是为了保障,在 CPU 指令重排序时,不论是单线程还是多线程的情况下,最终指令重排序后的结果都应该与代码本身的应有结果保持一致。对于单线程,可能在重排序后不会产生什么问题,但是对于多线程,这个规则可能就会产生一些问题~

CPU 指令重排序后,体现在代码层面的就是,写在后面的代码,可能在 CPU 重排序之后,就可能会先执行。

二、代码测试

测试代码

public class Test {
    public static int a, b, m, n;
    public static void main(String[] args) throws InterruptedException {
        int cnt = 0;
        Runnable r1 = () -> {
            a = 1;
            m = b;
        };

        Runnable r2 = () -> {
            b = 1;
            n = a;
        };

        while(true) {
            cnt ++;
            a = b = m = n = 0;

            Thread t1 = new Thread(r1);
            Thread t2 = new Thread(r2);

            t1.start();
            t2.start();
            t1.join();
            t2.join();

            if(m == 0 && n == 0) {
                System.err.print("第 " + cnt + " 次 " + "a = " + a + " b = " + b + " m = " + m + " n = " + n);
                break;
            }
            System.out.println("第 " + cnt + " 次 " + "a = " + a + " b = " +  b + " m = " + m + " n = " + n);
        }
    }
}

从测试代码中,我们可以推测一下可能产生的所有结果

可能的运行顺序~

        ① a = 1  m = b  b = 1  n = a
        ② a = 1  b = 1  m = b  n = a
        ③ a = 1  b = 1  n = a  m = b
        ④ b = 1  n = a  a = 1  m = b
        ⑤ b = 1  a = 1  n = a  m = b
        ⑥ b = 1  a = 1  m = b  n = a

会产生的结果

        ① a = 1  b = 1  m = 0  n = 1
        ② a = 1  b = 1  m = 1  n = 0
        ③ a = 1  b = 1  m = 1  n = 1

在推测的所有可能的结果中,不可能出现的结果是~

        a = 1  b = 1  m = 0  n = 0

如果产生了这种结果,那么 CPU 就产生了指令重排序,执行的顺序就可能变成以下情况~

        ① m = b  n = a  a = 1  b = 1
        ② m = b  n = a  b = 1  a = 1
        ③ n = a  m = b  a = 1  b = 1
        ④ n = a  m = b  b = 1  a = 1

测试结果

经过测试后发现,当运行至 209687 次时,CPU 指令重排序,得到下图的结果

可以说明,在 CPU 运行多线程时,可能会产生 CPU 指令重排序

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值