Java并发环境下指令重排会带来很多问题,那到底什么是指令重排?

解决方案 »

  1.   

    就是说Java 编译器可能重新排列源代码执行的顺序来优化编译的表现,比如 int a = 0, 
    int b = a + 1;
    int c = 2;在编译成bytecode 以后,执行的顺序可能是
    int c = 2;
    int b = a + 1;
    int a = 0;
      

  2.   

    大概意思就是,同一个方法中,两个变量的定义前后,会影响程序最后的运行结果。写后读 a = 1;b = a; 写一个变量之后,再读这个位置。
    写后写 a = 1;a = 2; 写一个变量之后,再写这个变量。
    读后写 a = b;b = 1; 读一个变量之后,再写这个变量。
    以上语句不可重排
    编译器不考虑多线程间的语义
    可重排: a=1;b=2;指令重排 会 破坏线程间的有序性。
    如:class OrderExample {
    int a = 0;
    boolean flag = false;public void writer() {
        a = 1;                   
        flag = true;           
    }public void reader() {
        if (flag) {                
            int i =  a +1;      
            ……
        }
    }
    }
    线程A首先执行writer()方法
    线程B线程接着执行reader()方法
    线程B在int i=a+1 是不一定能看到a已经被赋值为1因为在writer中,两句话顺序可能打乱线程A
    flag=true
    a=1线程B
    flag=true(此时a=0)避免指令重排:加上同步锁synchronized,当然,当保证同步时,就牺牲了程序的效率