指令重排序也被稱為處理器的亂序執行,在這種情況下盡管指令的執行順序可能沒有完全按照程序順序執行,但是由于指令的執行結果的提交(反應到寄存器和內存中),仍然是按照程序順序來的,因此處理器的指令重排序并不會對單線程的正確性產生影響。
什么是指令重排序?
在實際運行時,代碼指令可能并不是嚴格按照代碼語句順序執行的。大多數現代微處理器都會 采用將指令亂序執行(out-of-order execution,簡稱OoOE或OOE)的方法,在條件允許的 情況下,直接運行當前有能力立即執行的后續指令,避開獲取下一條指令所需數據時造成的等 待。
通過亂序執行的技術,處理器可以大大提高執行效率,而這就是指令重排。
指令重排序不是必然發生的,指令重排序會導致線程安全問題。
指令重排序也被稱為處理器的亂序執行,在這種情況下盡管指令的執行順序可能沒有完全按照程序順序執行,但是由于指令的執行結果的提交(反應到寄存器和內存中),仍然是按照程序順序來的,因此處理器的指令重排序并不會對單線程的正確性產生影響。
指令重排序不會對單線程程序的正確性產生影響,
但他可能導致多線程程序出現非預期結果。
測試邏輯
首先默認為x = 0; y = 0; a = 0; b = 0;然后開啟兩個線程;
線程1執行:a = 888; x = b;
線程2執行:b = 888; y = a;
有且只有x = b,y = a兩個同時先執行,才會出現x=y=0。
所以測試是否存在x=y=0觀察指令是否會出現重排現象。
public class OrderTest {
private static int x = 0, y = 0;
private static int a = 0, b = 0;
public static void main(String[] args) throws InterruptedException{
for(long i = 0; i < Long.MAX_VALUE; i++){
x = 0; y = 0; a = 0; b = 0;
CountDownLatch countDownLatch = new CountDownLatch(2);
Thread one = new Thread(new Runnable() {
@Override
public void run() {
a = 888;
x = b;
countDownLatch.countDown();
}
});
Thread two = new Thread(new Runnable() {
@Override
public void run() {
b = 888;
y = a;
countDownLatch.countDown();
}
});
one.start();
two.start();
//等待計數器變為0,即等待所有異步線程執行完畢
countDownLatch.await();
if(x == 0 && y == 0){
//x=y=0 只能是x = b;y = a;這兩個先執行
System.out.println("執行次數"+i+"發現x=y=0");
break;
}
}
}
}
結果:發現了指令重排現象