并发编程-volatile
线程安全的核心保障机制基于三个关键特性:原子性(Atomicity)、可见性(Visibility)和有序性(Ordering)。这三个特性共同确保多线程环境下共享资源的正确访问与修改,避免竞态条件、数据竞争等问题。
原子性(Atomicity):原子性指操作的最小单位不可分割,执行过程中不会被其他线程打断。实现原子性的方式有:1、synchronized关键字:通过锁机制保证方法或代码块在执行时独占资源;2、Atomic类,提供原子操作封装(如AtomicInteger
)。
可见性(Visibility):可见性确保一个线程对共享变量的修改能被其他线程立即反映出来。实现方式:1、volatile关键字:禁止指令重排序,确保每次访问主存最新值 2、synchronized锁:通过内部同步机制保证变量修改对其他线程可见
有序性(Ordering):有序性指线程执行指令的顺序与代码编写顺序一致。
线程安全的三大特性通过原子操作保障数据完整性、通过内存可见性避免数据不一致、通过有序性维护逻辑正确性。
下方示例演示volatile的可见性作用,没用volatile修饰之前的代码如下:
package com.gingko.thread;
public class VolatileDemo {private static boolean flag = false;private static int count = 100;public static void main(String[] args) {//开启一个线程,持续运行直到flag = truenew Thread(() -> {while (true) {if(flag) {System.out.println("count = " + count);break;}}}).start();try {Thread.sleep(100);//主线程改变flag和count值flag = true;count = 80;} catch (InterruptedException e) {e.printStackTrace();}}
}
程序运行后,由于子线程读取不到主线程修改的flag值,导致程序一直空转不停,效果如下:
添加了volatile 修饰flag标识后,主线程修改flag变量后,子线程可以获取到最新的值,程序输出count值(主线程修改后的值80)后,程序break推出。
程序运行结果如下,符合预期。