java 指令重排序測試

 

java中,synchronized和volatile均可以防止指令重排序,如今來驗證一下其實際效果。java

 

以下代碼所示,進行測試1:兩個線程,一個執行批量賦值操做,另一個檢測批量賦值操做是否亂序執行。ide

測試結果:確實會出現了亂序執行的狀況。測試

/** * 指令重排序測試 * * @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修飾spa

測試結果:再也不出現有亂序執行的結果,能夠推測是volatile保證了指令執行的有序性,不會被重排序。線程

 

以下代碼所示,進行測試3:在上面的批量賦值操做,以及批量檢測操做,兩個操做,都加上鎖,好比ReentrantLock,或者synchronizedcode

測試結果:再也不出現有亂序執行的結果,能夠推測加鎖,也能夠保證指令執行的有序性。其實這個能夠理解爲互斥訪問的特性,保證了有序性。blog

 

/** * 指令重排序測試 * * @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(); } } } }
相關文章
相關標籤/搜索