一.为什么会产生内存可见性问题
1.错误代码示例
package Thread;
import java.util.Scanner;
public class Demo3 {
static int flag = 0;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("线程1开始");
while (flag == 0) {
}
System.out.println("线程1结束");
});
Thread t2 = new Thread(() -> {
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
String in = sc.nextLine();
flag = 1;
System.out.println("线程2结束");
});
t1.start();
t2.start();
}
}
2.原因
在重复进行多次相同的读取操作时,编译器会对此过程进行优化,不再从内存进行读取,而是从寄存器进行读取,此时另一个线程修变量,寄存器中的值不变,产生内存可见性问题。
二.解决方案
1.使用volatile关键字进行修饰
volatile关键字在词义上是“不稳定的,易变的”,使用volatile关键字修饰后,变量固定从内存中读取,避免因为编译器优化产生内存可见性问题。
但使用volatile关键字后会降低程序运行效率。
代码示例:
package Thread;
import java.util.Scanner;
public class Demo3 {
volatile static int flag = 0;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("线程1开始");
while (flag == 0) {
}
System.out.println("线程1结束");
});
Thread t2 = new Thread(() -> {
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
String in = sc.nextLine();
flag = 1;
System.out.println("线程2结束");
});
t1.start();
t2.start();
}
}