Java中的内存一致性错误
当实现多线程的概念时,一个线程所做的更改可能对另一个线程不可见。这表明每个线程的视图相对于彼此是不一致的。这称为内存一致性错误。
CPU可能以不同的顺序启动主内存访问,而线程可能以不同的顺序访问它们。
当执行写操作时,通常会这样,从而避免了CPU等待时间。
写操作是原子操作,这意味着在执行写操作时,其他线程将不会执行其他操作。
除此之外,将为每个关联的CPU始终保持执行写入操作的顺序,而CPU可以以其他方式了解其他CPU的写入时间。此现象可能导致内存不一致。
如何避免内存不一致错误?
需要建立事前发生的关系,以便由单个线程执行内存写操作,这对于其他线程在同一内存上执行的读取操作可见。
“开始”功能和“加入”功能被视为事前发生关系。“启动”功能确保新创建的线程可见。“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("在它的增量之后是 "+m); } } void dec(){ for(int j=0;j<5;j++){ m = m-1; System.out.println("递减后是 "+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(); } }
输出结果
在它的增量之后是 3 递减后是 2 递减后是 2 递减后是 1 在它的增量之后是 3 递减后是 0 在它的增量之后是 1 在它的增量之后是 1 递减后是 0 在它的增量之后是 2
名为“class_shared”的类定义了一个静态值和一个void函数,该函数迭代一组数字,并将其递增并显示在控制台上。另一个名为“dec”的函数每次都会迭代一组数字和减量,并在控制台上显示输出。名为Demo的类包含创建该类实例并创建新线程的主要功能。覆盖此线程,并在此对象实例上调用run函数。第二个线程也做同样的事情。然后使用“开始”功能调用这两个线程。