Java原子类通过CAS与volatile协同实现无锁原子性:CAS保证操作原子性,volatile保障可见性与有序性,二者缺一不可;不同原子类适配多场景,但需注意ABA问题、自旋开销和单变量限制。

Java原子类靠CAS(Compare-And-Swap)+ volatile协同工作,不依赖锁,就能让多线程对共享变量的操作具备原子性、可见性和有序性。
核心机制是CAS指令
CAS是一种CPU硬件级原子操作,比如x86上的cmpxchg指令。它一次完成“读取—比较—更新”三步,不可分割:
- 读取内存地址当前值V
- 判断V是否等于预期值A
- 若相等,则将V设为新值B;否则不做修改,返回失败
Java通过Unsafe(JDK9起逐步由VarHandle替代)调用底层CAS方法,如compareAndSwapInt()。AtomicInteger的incrementAndGet()就是不断自旋执行CAS,直到成功为止。
volatile保障可见性与有序性
原子类内部字段(如AtomicInteger.value)都声明为volatile:
立即学习“Java免费学习笔记(深入)”;
- 写操作后立即刷入主内存,其他线程能立刻看到最新值
- 禁止编译器和处理器对volatile读写做重排序,保证操作顺序符合代码逻辑
没有volatile,CAS可能读到过期缓存值;没有CAS,volatile又无法保证复合操作(如自增)的原子性——二者缺一不可。
不同场景对应不同原子类
java.util.concurrent.atomic包按用途分五类,各司其职:
- 基本类型:AtomicInteger、AtomicLong、AtomicBoolean,适合计数器、开关标志等
- 数组元素:AtomicIntegerArray等,支持对数组某下标元素做原子更新,避免锁整个数组
- 对象引用:AtomicReference可原子更新任意对象;AtomicStampedReference带版本号,用于解决ABA问题
- 字段更新器:AtomicIntegerFieldUpdater等,用反射方式原子更新已有类的volatile字段,零拷贝改造旧代码
- 高性能累加器:LongAdder在高并发计数时比AtomicInteger更优,采用分段累加减少CAS竞争
CAS不是万能的,要注意三个典型局限
理解这些才能用得稳:
- ABA问题:值从A→B→A,CAS误判为未变。可用AtomicStampedReference(加版本号)或AtomicMarkableReference(加标记位)缓解
- 自旋开销:高竞争下反复失败重试,消耗CPU。LongAdder、Striped64等结构通过分散热点降低单点压力
- 仅限单变量:CAS只能保证一个内存位置的原子性。多个字段需同时更新?可封装成不可变对象,用AtomicReference整体替换










