一文彻底搞懂:volatile 与 CAS 核心原理、场景、实战

发布时间:2026/6/4 9:58:32

一文彻底搞懂:volatile 与 CAS 核心原理、场景、实战 大家在 Java 并发编程中经常被volatile和CAS搞晕 什么时候用 volatile什么时候用 CAS volatile 能保护集合吗 CAS 能实现无锁安全的多读多写吗这篇文章用最简单的代码 最清晰的结论一次性讲透。一、volatile 到底能干嘛1.1 核心能力保证可见性一个线程修改其他线程立刻看到保证单次读、单次赋值原子性不保证复合操作原子性i、if 操作 赋值都不行1.2 最经典用法状态开关一读一写public class Test { private volatile boolean stop false; // 写线程单个 public void stop() { stop true; } // 读线程单个/多个 public void run() { while (!stop) { // 业务逻辑 } } }✅安全✅无锁✅volatile 天生支持class Singleton { private static volatile Singleton instance; // volatile 关键 public static Singleton getInstance() { if (instance null) { // 第一次检查无锁 synchronized (Singleton.class) { // 加锁 if (instance null) { // 第二次检查有锁 instance new Singleton(); } } } return instance; } }二、volatile 做控制器保护其他变量一读一写volatile 可以作为开关安全保护另一个共享变量如 List。规则写线程先写数据 → 最后修改 volatile读线程先判断 volatile → 再读数据只能一读一写public class SafeDemo { private volatile boolean initialized false; private ListString dataList new ArrayList(); // 写线程仅1个 public void writer() { if (!initialized) { dataList.clear(); dataList.add(data1); dataList.add(data2); initialized true; } } // 读线程仅1个 public void reader() { if (initialized) { System.out.println(dataList.size()); initialized false; } } }✅无锁安全✅volatile 控制 共享变量保护❌不能多读多个读线程会并发冲突三、volatile List 正确用法替换引用volatile 只保证引用赋值可见 原子。正确姿势写线程新建 List → 赋值给 volatile读线程只读取引用单写 多读安全private volatile ListString list new ArrayList(); // 写线程唯一写 void write() { ListString newList new ArrayList(); newList.add(a); newList.add(b); list newList; // 安全 } // 读线程多个 void read() { ListString tmp list; for (String s : tmp) { System.out.println(s); } }✅无锁、安全、高效四、CAS 是什么比 volatile 强在哪4.1 核心区别volatile保证可见性、单次读写原子CAS保证单个变量复合操作原子性、ifset4.2 CAS 能做什么计数器incrementAndGet()条件更新compareAndSet(expect, update)无锁自旋锁保护其他变量实现多读多写五、CAS 实战无锁实现 List 多读多写利用AtomicBoolean做无锁互斥同一时间只有一个线程能写其他写线程自旋等待读线程必须等写完成public class SafeListHandler { private ListString list new ArrayList(); private final AtomicBoolean writing new AtomicBoolean(false); // 多写安全 public void write(String data) { while (!writing.compareAndSet(false, true)) { } try { list.add(data); } finally { writing.set(false); } } // 多读安全 public ListString read() { while (writing.get()) { } return new ArrayList(list); } }✅完全无锁✅多读多写安全✅List 被安全保护六、终极总结面试 / 工作必背volatile支持单次读、单次赋值原子支持一读一写、多读一写可做控制器保护其他变量只能一读一写不支持复合操作、多写CAS支持复合操作原子性、条件赋值支持多读多写单变量可做无锁自旋锁保护其他变量多读多写不支持多变量同时原子一句话口诀volatile单写多读无锁可见CAS单变量原子无锁互斥想无锁安全多读多写用 CAS 做自旋锁volatile即使忙等待也不能多读多写因为不能解决原子性GETSET因为写只能同时一个在操作只有原子性 get/set 的变量才能安全多写只要不是纯 get/set多写必须用 CAS 或锁。中断例外中断没有并发问题volatile 和 cas 都是用于单变量。

相关新闻