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();
   }
}

Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

输出

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 次浏览

启动您的职业生涯

完成课程获得认证

开始学习
广告