重排序
线程内部两行代码时,执行顺序和源代码中的书写顺序不一致,就是发生了重排序,重排序现象是由以下结果导致:
- 编译器优化:包括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;
}
}
}
}
Comments NOTHING