volatile 能保证内存可⻅性
运行下面的例子:
package Demo03;import java.util.Scanner;public class demo01 {private static int flag = 0;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (flag == 0) {}System.out.println("t1 线程结束");});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);System.out.println("请输入flag的值:");flag = scanner.nextInt();});t2.start();t1.start();}
}
运行后 t1线程并未结束 这显然是个bug
原因分析:
一个线程读取,一个线程修改 修改线程修改的值,并没有被读线程读到。
导致内存可见性问题的因素:
缓存:现代处理器为了提高性能,通常会将频繁访问的数据存储在其私有的高速缓存中。当多个线程运行在不同的CPU核心上时,它们可能会读取到各自缓存中的不同版本的数据,而不是主内存中的最新值
即:t1 读的是⾃⼰⼯作内存中的内容. 当t2对flag变量进⾏修改,此时t1感知不到flag的变化
修改代码:添加关键字 volatile:
package Demo03;import java.util.Scanner;public class demo01 {private volatile static int flag = 0;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (flag == 0) {}System.out.println("t1 线程结束");});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);System.out.println("请输入flag的值:");flag = scanner.nextInt();});t2.start();t1.start();}
}
运行结果:
volatile 不保证保证原子性
运行下面例子:
package Demo03;import java.util.Scanner;public class demo01 {private volatile static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i <50000 ; i++) {count++;}});Thread t2 = new Thread(() -> {for (int i = 0; i <50000 ; i++) {count++;}});t2.start();t1.start();t1.join();t2.join();System.out.println(count);}
}
运行结果不能保证原子性