在 Java 中,原子类(Atomic Classes) 是 java.util.concurrent.atomic
包下的一组类,它们基于 CAS(Compare-And-Swap) 实现了线程安全的原子操作,避免了使用 synchronized
锁带来的性能开销,是构建高性能并发程序的重要工具。
✅ 一、常用的原子类及使用场景
1. 基本类型原子类
类名 | 类型 | 说明 |
---|
AtomicInteger | int | 线程安全的整型计数器 |
AtomicLong | long | 线程安全的长整型计数器 |
AtomicBoolean | boolean | 线程安全的布尔值,常用于状态标记 |
示例:
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // 原子自增
counter.compareAndSet(1, 2); // CAS 操作
2. 数组类型原子类
类名 | 类型 | 说明 |
---|
AtomicIntegerArray | int[] | 线程安全的整型数组 |
AtomicLongArray | long[] | 线程安全的长整型数组 |
AtomicReferenceArray | Object[] | 线程安全的引用类型数组 |
示例:
AtomicIntegerArray arr = new AtomicIntegerArray(10);
arr.incrementAndGet(0); // 对索引0的元素进行原子自增
3. 引用类型原子类
类名 | 类型 | 说明 |
---|
AtomicReference<V> | V | 线程安全的引用类型 |
AtomicReferenceFieldUpdater | 用于更新对象中的字段 | 高性能字段更新 |
AtomicMarkableReference | 带标记位的引用 | 解决 ABA 问题 |
示例:
AtomicReference<String> ref = new AtomicReference<>("A");
ref.compareAndSet("A", "B"); // 原子更新引用
4. 复合类型原子类(解决 ABA 问题)
类名 | 类型 | 说明 |
---|
AtomicStampedReference | 带版本号 | 用于解决 ABA 问题 |
AtomicMarkableReference | 带标记位 | 判断引用是否被修改过 |
示例(ABA 问题):
AtomicStampedReference<Integer> asr = new AtomicStampedReference<>(100, 0);
int stamp = asr.getStamp();
asr.compareAndSet(100, 101, stamp, stamp + 1);
5. 累加器类(Java 8+)
类名 | 类型 | 说明 |
---|
LongAdder | long | 高并发累加器,性能优于 AtomicLong |
DoubleAdder | double | 浮点数累加器 |
LongAccumulator | long | 支持自定义累加函数(如 max、min) |
DoubleAccumulator | double | 同上,浮点数版本 |
示例:
LongAdder adder = new LongAdder();
adder.add(100); // 高并发下的高效累加
long total = adder.sum(); // 获取总和
✅ 二、原子类的底层实现原理
- 基于 CAS 操作:通过
Unsafe
类提供的 CAS 方法实现原子性更新。
- volatile 保证可见性:原子类内部的变量使用
volatile
修饰,确保多线程之间的可见性。
- 分段锁优化(如 LongAdder):将竞争分散到多个变量上,提高高并发下的性能。
✅ 三、实际使用场景(结合业务)
使用场景 | 所用原子类 | 说明 |
---|
高并发计数器 | LongAdder | 替代 AtomicLong ,提升性能 |
状态标志 | AtomicBoolean | 控制线程执行状态 |
缓存刷新 | AtomicReference | 安全地更新缓存对象 |
ABA 问题处理 | AtomicStampedReference | 带版本号的引用更新 |
统计指标 | LongAdder / DoubleAdder | 统计请求数、响应时间等 |
自定义聚合 | LongAccumulator | 求最大值、最小值、乘积等 |
✅ 四、总结回答(面试模板)
我在项目中使用过 Java 中的多个原子类,包括 AtomicInteger
、AtomicLong
、AtomicReference
、AtomicBoolean
,以及 Java 8 引入的高性能累加器 LongAdder
和 DoubleAdder
。这些类基于 CAS 和 volatile 实现线程安全,适用于各种并发场景。例如:
- 使用
LongAdder
来统计高并发下的请求数;
- 使用
AtomicReference
来安全地更新缓存对象;
- 使用
AtomicStampedReference
来解决 ABA 问题;
- 使用
AtomicBoolean
控制线程的运行状态。
这些类相比 synchronized
更加轻量,性能更好,适合构建高性能的并发程序。
如果你在实际项目中确实使用过这些类,建议结合具体场景说明,这样面试官更容易认可你的实战经验。