10-重排序

nobility 发布于 2021-05-14 2539 次阅读


重排序

线程内部两行代码时,执行顺序和源代码中的书写顺序不一致,就是发生了重排序,重排序现象是由以下结果导致:

  • 编译器优化:包括JVM,JIT实时编译器等
  • CPU优化:编译器未发生重排序,CPU也可能对指令进行重排序
  • 内存重排现象:由于线程之间的变量不可见性,导致表面上的重排序(其实没有发生重排序)比如:线程1进行修改值,但是未写入主内存时,也就是线程2未看到修改,读出来的是未经修改的值

重排序优化的目的是为了直接允许当前能立即执行的后续指令,避开回去下一条指令所需数据造成的等待,从而提高运行效率

下面代码验证重排序

public class Main {
  private static int a = 0;
  private static int b = 0;
  private static int x = 0;
  private static int y = 0;

  public static void main(String[] args) throws InterruptedException {
    while (true) {
      a = b = x = y = 0;
      Thread thread1 = new Thread(() -> {
        a = 1;
        x = b;
      });
      Thread thread2 = new Thread(() -> {
        b = 2;
        y = a;
      });
      thread1.start();
      thread2.start();

      thread1.join();
      thread2.join();
      //保证线程1和线程2先执行结束
      /**
       * thread1先运行完毕,thread2再运行,                    a=1,b=2,x=0,y=1
       * thread2先运行完毕,thread1再运行,                    a=1,b=2,x=2,y=0
       * thread1和2交叉运行,thread1部分运行,thread2完整运行,a=1,b=2,x=2,y=1
       * thread1和2交叉运行,thread1部分运行,thread2部分运行,a=1,b=2,x=2,y=1
       * thread1和2交叉运行,thread2部分运行,thread1完整运行,a=1,b=2,x=2,y=1
       * thread1和2交叉运行,thread2部分运行,thread1部分运行,a=1,b=2,x=2,y=1
       * 出现重新排序,可能会出现                              a=1,b=2,x=0,y=0
       */
      System.out.println("a=" + a + ",b=" + b + ",x=" + x + ",y=" + y);
      if (x == 0 && y == 0) {
        System.out.println("证实了有重排序");
        break;
      }
    }
  }
}
此作者没有提供个人介绍
最后更新于 2021-05-14