Java中复合操作需显式保证原子性,可通过synchronized、ReentrantLock、AtomicReference+ CAS或不可变对象+原子引用四种方式实现,分别适用于不同并发场景。

Java 中的复合操作本身不是原子的,必须通过显式手段保证其原子性。所谓复合操作,是指由多个步骤组成、逻辑上不可分割的一组操作,比如“先读取再更新再写入”(如 count++ 或“检查后执行”类逻辑)。这类操作天然存在竞态条件,仅靠普通变量或非同步方法无法保障线程安全。
用 synchronized 同步临界区
最直接的方式是将整个复合操作包裹在 synchronized 块或同步方法中,确保同一时刻只有一个线程能执行该段逻辑。
- 适用于任意复杂度的复合操作,不限于单个变量
- 能同时保证原子性、可见性和有序性
- 例如银行转账:读取账户A余额、读取账户B余额、验证A够扣、A减、B加——这五步必须整体原子执行
用 Lock 显式控制执行边界
相比 synchronized,ReentrantLock 提供更灵活的锁管理,适合需要中断响应、超时获取或分段加锁的复合场景。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 必须配合
try-finally确保锁最终释放 - 支持条件等待(
Condition),可用于实现“等待某状态满足后再执行复合逻辑” - 例如:生产者在缓冲区满时等待,消费者取走数据后通知,整个“检查+等待+执行”构成带条件的复合操作
用 AtomicReference + CAS 循环重试
对于基于对象引用的复合操作(如更新某个字段并返回旧值),可使用 AtomicReference 的 compareAndSet 或 updateAndGet 方法,配合自定义函数实现无锁原子更新。
立即学习“Java免费学习笔记(深入)”;
- 底层依赖硬件级 CAS 指令,失败时自动重试,避免阻塞
- 要求更新逻辑是纯函数(无副作用、不依赖外部状态)
- 例如:原子地将用户对象的邮箱字段从旧值更新为新值,并确保过程中没人并发修改过该对象
用不可变对象 + 原子引用替换
当复合操作本质是“构造新状态并整体替换”,可设计为创建不可变对象,再用 AtomicReference.set() 原子更新引用。
- 引用赋值本身是原子的(即使对象很大)
- 所有读取方看到的要么是旧完整状态,要么是新完整状态,不会看到中间态
- 典型应用:配置对象热更新、状态机迁移(如从“初始化”到“运行中”)

















