Java并发12:volatile关键字深度解析 - 轻量级同步机制

引言:volatile能解决什么问题? 看这个经典的"停止线程"问题: public class StopThread { private boolean stop = false; // 没有volatile public void run() { new Thread(() -> { while (!stop) { // 执行任务 doWork(); } System.out.println("线程停止"); }).start(); // 1秒后停止线程 Thread.sleep(1000); stop = true; System.out.println("已设置stop=true"); } } 运行结果: 已设置stop=true (线程永远不会停止!) 加上volatile后: private volatile boolean stop = false; // 加volatile 运行结果: 已设置stop=true 线程停止 ← 正常停止了 三个问题: 为什么没有volatile时线程看不到stop = true? volatile做了什么让线程能看到了? volatile是万能的吗?什么时候不能用? 本篇文章将深入volatile的底层原理,彻底理解这个轻量级同步机制。 一、volatile解决的两大问题 1.1 可见性问题 问题根源:CPU缓存 CPU 0 CPU 1 ↓ ↓ L1 Cache (stop=false) L1 Cache (stop=false) ↓ ↓ 主内存 (stop=false) 时刻1: CPU 0修改stop=true CPU 0: L1 Cache (stop=true) ← 只在CPU 0的缓存中 CPU 1: L1 Cache (stop=false) ← CPU 1看不到! volatile的解决方案: ...

2025-11-20 · maneng

Java并发08:并发编程的三大核心问题 - 原子性、可见性、有序性

引言:为什么synchronized能解决所有问题? // volatile只解决部分问题 private volatile int count = 0; count++; // 仍然不安全! // synchronized解决所有问题 private int count = 0; public synchronized void increment() { count++; // 安全 } 为什么? 关键在于理解并发编程的三大核心问题: 原子性(Atomicity) 可见性(Visibility) 有序性(Ordering) 一、原子性(Atomicity) 1.1 什么是原子性? 定义:一个操作或多个操作,要么全部执行且执行过程不被打断,要么都不执行。 int a = 10; // ✅ 原子操作 a++; // ❌ 非原子操作(3条指令) 1.2 哪些操作是原子的? 原子操作: // ✅ 基本类型的读写(long/double除外) int a = 1; boolean b = true; // ✅ 引用类型的读写 Object obj = new Object(); // ✅ volatile变量的读写 volatile int count = 0; count = 1; // 原子的 非原子操作: // ❌ long/double(64位,需要两次操作) long value = 123L; // 非原子的(未加volatile) // ❌ 复合操作 count++; // read-modify-write array[index]++; // 非原子 // ❌ check-then-act if (map.get(key) == null) { map.put(key, value); // 竞态条件 } 1.3 如何保证原子性? 方式1:synchronized public synchronized void increment() { count++; // 整个方法是原子的 } 方式2:Lock private Lock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } 方式3:原子类 private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // 原子操作 } 二、可见性(Visibility) 2.1 什么是可见性? 定义:当一个线程修改了共享变量,其他线程能够立即看到这个修改。 ...

2025-11-20 · maneng

Java并发11:happens-before原则 - JMM的核心规则

引言:如何判断程序是否线程安全? 看这段代码,能否确定线程安全? public class DataRace { private int data = 0; private boolean ready = false; // 线程1 public void writer() { data = 42; // 1 ready = true; // 2 } // 线程2 public void reader() { if (ready) { // 3 System.out.println(data); // 4 一定输出42吗? } } } 三个问题: 线程2能看到ready = true吗?(可见性) 如果看到ready = true,能保证看到data = 42吗?(有序性) 如何用形式化的规则判断? 传统方法是分析各种可能的执行顺序,但这太复杂了! JMM的解决方案:happens-before原则 happens-before是JMM的核心规则,它定义了: 什么时候一个操作的结果对另一个操作可见 什么时候两个操作不能重排序 如何建立正确的并发语义 掌握happens-before原则,就能快速判断程序是否线程安全。 一、happens-before的定义 1.1 形式化定义 happens-before关系(简写为 hb): 如果操作A happens-before 操作B,记作 A hb B,则: 可见性保证:A的结果对B可见 有序性保证:A在B之前执行(从程序语义角度) 注意: ...

2025-11-20 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...