java.util.concurrent.atomic(简称 Atomic 包)是 Java 并发编程的核心基础包,JDK 1.5 引入,专为 多线程环境下的原子操作 设计。它基于 CAS(Compare-And-Swap)原子指令 + volatile 可见性 实现无锁并发,避免了 synchronized 等锁机制的线程阻塞 / 上下文切换开销,兼顾线程安全与高性能。
核心目标:解决多线程对单个变量的 “读取 - 修改 - 写入” 复合操作原子性问题(如 i++、count += n),同时提供可见性和有序性保证(依赖 volatile 和 CAS 语义)。
一、核心设计思想
Atomic 包的所有类遵循统一设计原则,底层依赖 sun.misc.Unsafe 类(封装 CPU 原子指令)实现核心能力:
-
无锁设计:不依赖锁(
synchronized/Lock),通过 CAS 自旋重试解决并发冲突,轻量级且高效(低冲突场景性能远超锁)。 -
volatile 可见性:所有原子类的核心变量(如
AtomicInteger的value)均被volatile修饰,确保修改后立即写回主内存,其他线程实时读取最新值。 -
CAS 原子性:依赖 CPU 提供的
cmpxchg原子指令,实现 “比较 - 替换” 的原子操作,核心逻辑:- 读取当前内存值
V; - 比较
V与预期值E是否一致; - 若一致,将
V更新为新值N,返回成功;若不一致,重试(自旋)直到成功。
- 读取当前内存值
-
API 简洁性:提供直观的原子操作方法(如
incrementAndGet()、compareAndSet()),无需手动处理锁逻辑。
二、包结构与核心类分类
Atomic 包的类按功能可分为 5 大类,覆盖 基本类型、引用类型、数组、字段更新、复合操作 等场景,核心类如下:
| 类别 | 核心类 | 功能描述 |
|---|---|---|
| 基本类型原子类 | AtomicInteger、AtomicLong、AtomicBoolean、AtomicByte | 原子操作 int/long/boolean/byte 等基本类型 |
| 引用类型原子类 | AtomicReference、AtomicStampedReference、AtomicMarkableReference | 原子更新对象引用,解决 ABA 问题 |
| 数组类型原子类 | AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray | 原子更新数组元素(避免数组元素并发冲突) |
| 字段更新器原子类 | AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater | 反射机制原子更新对象的字段(无需修改原类) |
| 复合操作原子类(JDK8+) | LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator | 高并发场景优化,支持自定义复合操作(如最大值统计) |
三、各类核心类详解(含使用场景)
1. 基本类型原子类(最常用)
针对基本类型的原子增减、赋值、比较替换,解决简单数值的并发安全问题。
-
核心类:
AtomicInteger(int)、AtomicLong(long)、AtomicBoolean(boolean)。 -
核心 API:
incrementAndGet()(自增)、addAndGet(delta)(累加)、compareAndSet(expect, update)(比较替换)。 -
适用场景:计数器(接口调用量、QPS)、序号生成器(订单 ID)、简单状态标记(如 “已处理数量”)。
-
示例:
java
运行
AtomicInteger counter = new AtomicInteger(0); counter.incrementAndGet(); // 原子自增(++i) counter.addAndGet(5); // 原子累加 5 boolean success = counter.compareAndSet(6, 10); // 若当前值为6,更新为10
2. 引用类型原子类
针对 对象引用 的原子操作,避免多线程修改引用导致的对象不一致,解决 CAS 中的 ABA 问题。
-
核心类:
AtomicReference:普通引用原子更新(如原子替换配置对象);AtomicStampedReference:带版本号的引用(解决 ABA 问题,如链表操作);AtomicMarkableReference:带布尔标记的引用(简化版 ABA 解决方案,仅判断是否修改)。
-
适用场景:原子更新配置对象、单例对象、缓存更新、链表节点操作。
-
示例(
AtomicStampedReference解决 ABA):java
运行
// 初始值"A",版本戳0 AtomicStampedReference<String> stampedRef = new AtomicStampedReference<>("A", 0); // 比较并替换:预期值"A"、版本0 → 更新为"C"、版本1(版本不匹配则失败) boolean success = stampedRef.compareAndSet("A", "C", 0, 1);
3. 数组类型原子类
原子更新数组元素,避免多线程修改数组时的并发冲突(如分桶计数场景)。
-
核心类:
AtomicIntegerArray(int[])、AtomicLongArray(long[])、AtomicReferenceArray(引用数组)。 -
核心 API:
getAndIncrement(index)(指定索引原子自增)、compareAndSet(index, expect, update)(指定索引比较替换)。 -
适用场景:分桶计数(如按用户 ID 分桶统计访问量)、原子更新缓存数组。
-
示例:
java
运行
AtomicIntegerArray bucketCounts = new AtomicIntegerArray(10); // 10个分桶 int bucketIndex = Math.abs("user123".hashCode()) % 10; bucketCounts.incrementAndGet(bucketIndex); // 对应分桶原子自增
4. 字段更新器原子类
通过 反射机制 原子更新对象的实例字段或静态字段,无需修改原类源码(如第三方库类)。
-
核心类:
AtomicIntegerFieldUpdater(int字段)、AtomicLongFieldUpdater(long字段)、AtomicReferenceFieldUpdater(引用字段)。 -
关键限制:目标字段必须是
volatile(保证可见性)、非final(可修改)、非private(反射可访问)。 -
适用场景:修改第三方库类的字段、无需侵入原类的原子更新。
-
示例:
java
运行
// 第三方类(字段为 volatile int) class ThirdParty { volatile int count; } // 创建字段更新器 AtomicIntegerFieldUpdater<ThirdParty> updater = AtomicIntegerFieldUpdater.newUpdater(ThirdParty.class, "count"); ThirdParty obj = new ThirdParty(); updater.incrementAndGet(obj); // 原子自增 count 字段
5. 复合操作原子类(JDK8+ 新增)
针对高并发场景优化,内部分桶存储减少 CAS 冲突,支持自定义复合操作(如最大值、最小值统计),性能远超传统原子类。
-
核心类:
LongAdder/DoubleAdder:高并发累加(AtomicLong/AtomicDouble的高性能替代);LongAccumulator/DoubleAccumulator:支持自定义复合操作(如最大值、自定义聚合逻辑)。
-
适用场景:高并发 QPS 统计、流量统计、复杂聚合计算(如实时最大值)。
-
示例(
LongAdder高并发计数):java
运行
LongAdder qpsAdder = new LongAdder(); qpsAdder.increment(); // 原子自增(分桶存储,冲突少) System.out.println("QPS:" + qpsAdder.sum()); // 合并分桶结果
四、Atomic 包的核心特性与限制
1. 核心优势
- 高性能:无锁设计,避免线程阻塞和上下文切换,低冲突场景下性能是
synchronized的数倍。 - 线程安全:通过 CAS 原子指令和 volatile 保证原子性、可见性、有序性。
- API 简洁:无需手动处理锁逻辑,直接调用原子操作方法(如
incrementAndGet()),开发效率高。 - 兼容性:底层依赖 JVM 封装的 CPU 原子指令,适配不同操作系统(Windows、Linux)和 CPU 架构(x86、ARM)。
2. 关键限制
- 仅支持单变量原子性:单个 API 是原子的,但多个原子操作组合(如 “先自增再判断阈值”)不原子,需手动用
compareAndSet()循环包裹。 - ABA 问题:传统原子类(如
AtomicInteger、AtomicReference)存在 ABA 漏洞,需用AtomicStampedReference或AtomicMarkableReference解决。 - 高冲突场景性能下降:若上千线程同时 CAS 操作同一变量,自旋重试会消耗大量 CPU,此时需改用
LongAdder(分桶)或锁机制。 - 不支持批量操作:原子类仅针对单个变量 / 数组元素,批量更新多个变量需额外同步。
五、Atomic 包的典型应用场景
- 高并发计数器:接口调用量、QPS、用户在线数、订单量统计(
AtomicInteger/AtomicLong/LongAdder)。 - 序号生成器:订单 ID、用户 ID、请求序列号生成(
AtomicLong)。 - 原子更新配置:多线程环境下替换整个配置对象(
AtomicReference)。 - 分桶统计:按哈希分桶减少并发冲突(
AtomicIntegerArray/AtomicLongArray)。 - 第三方类字段更新:无需修改源码,原子更新第三方库的字段(
AtomicIntegerFieldUpdater)。 - 高并发聚合计算:实时统计最大值、最小值、自定义聚合逻辑(
LongAccumulator)。
六、使用建议与选型指南
| 场景需求 | 推荐类 | 替代方案 |
|---|---|---|
简单 int/long 计数 | AtomicInteger/AtomicLong | 高并发用 LongAdder |
| 布尔状态标记 | AtomicBoolean | AtomicReference<Boolean> |
| 原子更新对象引用 | AtomicReference | 需避免 ABA 用 AtomicStampedReference |
| 数组元素原子操作 | AtomicIntegerArray/AtomicLongArray | 手动加锁(性能差) |
| 第三方类字段原子更新 | AtomicIntegerFieldUpdater 等 | 无(唯一非侵入式方案) |
| 高并发亿级计数 | LongAdder | AtomicLong(低并发可用) |
| 复杂聚合计算(最大值 / 自定义) | LongAccumulator | 锁 + 普通变量(代码繁琐) |
核心原则:
- 低并发、简单场景:优先用
AtomicInteger/AtomicLong(API 简洁,学习成本低); - 高并发计数:用
LongAdder(分桶无锁,性能最优); - 引用更新 / ABA 问题:用
AtomicReference/AtomicStampedReference; - 第三方类 / 数组场景:用字段更新器 / 数组原子类;
- 复合逻辑 / 多变量操作:用
synchronized或Lock(保证整体原子性)。
七、总结
java.util.concurrent.atomic 是 Java 并发编程的 基础工具包,核心价值是 “无锁实现单变量原子操作”,平衡了线程安全与高性能。它屏蔽了底层 CPU 原子指令和 volatile 语义的复杂性,提供了简洁易用的 API,是计数器、序号生成器、原子配置更新等场景的首选方案。
理解 Atomic 包的核心原理(CAS + volatile)和各类的适用场景,能帮助开发者在多线程编程中避免并发问题,同时提升程序性能。它也是很多高级并发工具(如 ConcurrentHashMap、ThreadPoolExecutor)的底层依赖。