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”函式呼叫這兩個執行緒。

更新於:2020年7月14日

493 次瀏覽

啟動您的職業生涯

完成課程獲得認證

開始學習
廣告