zoukankan      html  css  js  c++  java
  • java 指令重排序测试

    java中,synchronized和volatile都可以防止指令重排序,现在来验证一下其实际效果。

    如下代码所示,进行测试1:两个线程,一个执行批量赋值操作,另外一个检测批量赋值操作是否乱序执行。

    测试结果:确实会出现了乱序执行的情况。

    /**
     * 指令重排序测试
     *
     * @author zhangxz
     * @date 2019-11-17 16:40
     */
    
    public class CmdReorderTest {
    
        private static int a = 0;
        private static int b = 0;
        private static int c = 0;
        private static int d = 0;
        private static int e = 0;
        private static int f = 0;
        private static int g = 0;
        private static int h = 0;
    
        public static void main(String[] args) throws InterruptedException {
    
            for (int i = 0; i < 500000; i++) {
                //join可以保证线程a b都执行完成之后,再继续下一次循环
                ThreadA threadA = new ThreadA();
                threadA.start();
    
                ThreadB threadB = new ThreadB();
                threadB.start();
    
                threadA.join();
                threadB.join();
    
                //清空数据,便于测试
                a = 0;
                b = 0;
                c = 0;
                d = 0;
                e = 0;
                f = 0;
                g = 0;
                h = 0;
            }
        }
    
        static class ThreadA extends Thread {
            @Override
            public void run() {
                a = 1;
                b = 1;
                c = 1;
                d = 1;
                e = 1;
                f = 1;
                g = 1;
                h = 1;
            }
        }
    
        static class ThreadB extends Thread {
            @Override
            public void run() {
                if (b == 1 && a == 0) {
                    System.out.println("b=1");
                }
                if (c == 1 && (a == 0 || b == 0)) {
                    System.out.println("c=1");
                }
                if (d == 1 && (a == 0 || b == 0 || c == 0)) {
                    System.out.println("d=1");
                }
                if (e == 1 && (a == 0 || b == 0 || c == 0 || d == 0)) {
                    System.out.println("e=1");
                }
                if (f == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0)) {
                    System.out.println("f=1");
                }
                if (g == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0 || f == 0)) {
                    System.out.println("g=1");
                }
                if (h == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0 || f == 0 || g == 0)) {
                    System.out.println("h=1");
                }
            }
        }
    
    }

    测试2:把上面代码的所有静态变量,都使用volatile修饰

    测试结果:不再出现有乱序执行的结果,可以推测是volatile保证了指令执行的有序性,不会被重排序。

    如下代码所示,进行测试3:在上面的批量赋值操作,以及批量检测操作,两个操作,都加上锁,比如ReentrantLock,或者synchronized

    测试结果:不再出现有乱序执行的结果,可以推测加锁,也可以保证指令执行的有序性。其实这个可以理解为互斥访问的特性,保证了有序性。

    /**
     * 指令重排序测试
     *
     * @author zhangxz
     * @date 2019-11-17 16:40
     */
    
    public class CmdReorderTest {
    
        private static int a = 0;
        private static int b = 0;
        private static int c = 0;
        private static int d = 0;
        private static int e = 0;
        private static int f = 0;
        private static int g = 0;
        private static int h = 0;
    
    /*
        private static volatile int a = 0;
        private static volatile int b = 0;
        private static volatile int c = 0;
        private static volatile int d = 0;
        private static volatile int e = 0;
        private static volatile int f = 0;
        private static volatile int g = 0;
        private static volatile int h = 0;
    */
    
        private static ReentrantLock lock = new ReentrantLock();
    
        public static void main(String[] args) throws InterruptedException {
    
            for (int i = 0; i < 500000; i++) {
                //join可以保证线程a b都执行完成之后,再继续下一次循环
                ThreadA threadA = new ThreadA();
                threadA.start();
    
                ThreadB threadB = new ThreadB();
                threadB.start();
    
                threadA.join();
                threadB.join();
    
                //清空数据,便于测试
                a = 0;
                b = 0;
                c = 0;
                d = 0;
                e = 0;
                f = 0;
                g = 0;
                h = 0;
            }
        }
    
        static class ThreadA extends Thread {
            @Override
            public void run() {
                lock.lock();
                try {
                    a = 1;
                    b = 1;
                    c = 1;
                    d = 1;
                    e = 1;
                    f = 1;
                    g = 1;
                    h = 1;
                } finally {
                    lock.unlock();
                }
            }
        }
    
        static class ThreadB extends Thread {
            @Override
            public void run() {
                lock.lock();
                try {
                    if (b == 1 && a == 0) {
                        System.out.println("b=1");
                    }
                    if (c == 1 && (a == 0 || b == 0)) {
                        System.out.println("c=1");
                    }
                    if (d == 1 && (a == 0 || b == 0 || c == 0)) {
                        System.out.println("d=1");
                    }
                    if (e == 1 && (a == 0 || b == 0 || c == 0 || d == 0)) {
                        System.out.println("e=1");
                    }
                    if (f == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0)) {
                        System.out.println("f=1");
                    }
                    if (g == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0 || f == 0)) {
                        System.out.println("g=1");
                    }
                    if (h == 1 && (a == 0 || b == 0 || c == 0 || d == 0 || e == 0 || f == 0 || g == 0)) {
                        System.out.println("h=1");
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
    
    }
  • 相关阅读:
    【习题整理】分块+莫队(未完待续)
    【bzoj4198】【Noi2015】荷马史诗
    【bzoj2006】【NOI2015】超级钢琴
    【bzoj1029】【JSOI2007】建筑抢修
    【bzoj1483】【HNOI2009】梦幻布丁
    【bzoj4195】【NOI2015】程序自动分析
    Rearrangement inequality
    hdu1047
    hdu1046
    hdu1045
  • 原文地址:https://www.cnblogs.com/zhangxuezhi/p/11885519.html
Copyright © 2011-2022 走看看