面试题:你使用过 Java 中的哪些原子类?

在 Java 中,原子类(Atomic Classes)java.util.concurrent.atomic 包下的一组类,它们基于 CAS(Compare-And-Swap) 实现了线程安全的原子操作,避免了使用 synchronized 锁带来的性能开销,是构建高性能并发程序的重要工具。


✅ 一、常用的原子类及使用场景

1. 基本类型原子类

类名类型说明
AtomicIntegerint线程安全的整型计数器
AtomicLonglong线程安全的长整型计数器
AtomicBooleanboolean线程安全的布尔值,常用于状态标记

示例:

AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); // 原子自增
counter.compareAndSet(1, 2); // CAS 操作

2. 数组类型原子类

类名类型说明
AtomicIntegerArrayint[]线程安全的整型数组
AtomicLongArraylong[]线程安全的长整型数组
AtomicReferenceArrayObject[]线程安全的引用类型数组

示例:

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+)

类名类型说明
LongAdderlong高并发累加器,性能优于 AtomicLong
DoubleAdderdouble浮点数累加器
LongAccumulatorlong支持自定义累加函数(如 max、min)
DoubleAccumulatordouble同上,浮点数版本

示例:

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 中的多个原子类,包括 AtomicIntegerAtomicLongAtomicReferenceAtomicBoolean,以及 Java 8 引入的高性能累加器 LongAdderDoubleAdder。这些类基于 CAS 和 volatile 实现线程安全,适用于各种并发场景。例如:

  • 使用 LongAdder 来统计高并发下的请求数;
  • 使用 AtomicReference 来安全地更新缓存对象;
  • 使用 AtomicStampedReference 来解决 ABA 问题;
  • 使用 AtomicBoolean 控制线程的运行状态。

这些类相比 synchronized 更加轻量,性能更好,适合构建高性能的并发程序。


如果你在实际项目中确实使用过这些类,建议结合具体场景说明,这样面试官更容易认可你的实战经验。

THE END
喜欢就支持一下吧
点赞6 分享