Java中的記憶體一致性錯誤
當實現多執行緒的概念時,一個執行緒所做的更改可能對另一個執行緒不可見。這表明每個執行緒的檢視彼此不一致。這被稱為記憶體一致性錯誤。
CPU可能以不同的順序發起主記憶體訪問,而執行緒可能以不同的順序訪問它們。
當執行寫操作時,這通常是正確的,從而避免了CPU等待時間。
寫操作是原子操作,這意味著在執行寫操作時,其他執行緒不會執行任何其他操作。
除此之外,寫操作執行的順序對於每個關聯的CPU將保持一致,而CPU可以以不同的方式理解其他CPU的寫時間。這種現象可能導致記憶體不一致。
如何避免記憶體不一致錯誤?
需要建立一個“先行發生”關係,以便由單個執行緒執行記憶體寫入,並且這對於其他執行緒對同一記憶體執行的讀取操作可見。
“start”函式和“join”函式被認為是先行發生關係。“start”函式確保新建立的執行緒可見。“join”函式確保可見的執行緒已加入到其他執行緒。
示例
import java.io.*; class class_shared{ static int m=2; void inc(){ for(int j=0;j<5;j++){ m = m+1; System.out.println("After its increment is "+m); } } void dec(){ for(int j=0;j<5;j++){ m = m-1; System.out.println("After its decrement is "+m); } } } public class Demo{ public static void main(String[] args){ final class_shared my_inst = new class_shared(); Thread my_t_1 = new Thread(){ @Override public void run(){ my_inst.inc(); } }; Thread my_t_2 = new Thread(){ @Override public void run(){ my_inst.dec(); } }; my_t_1.start(); my_t_2.start(); } }
輸出
After its increment is 3 After its decrement is 2 After its decrement is 2 After its decrement is 1 After its increment is 3 After its decrement is 0 After its increment is 1 After its increment is 1 After its decrement is 0 After its increment is 2
名為“class_shared”的類定義了一個靜態值和一個void函式,該函式迭代一組數字,遞增它並在控制檯上顯示它。另一個名為“dec”的函式迭代一組數字,每次遞減並顯示控制檯上的輸出。名為Demo的類包含建立類例項並建立新執行緒的主函式。此執行緒被覆蓋,並且在此物件例項上呼叫run函式。第二個執行緒也執行相同的操作。然後使用“start”函式呼叫這兩個執行緒。
廣告