1. AtomicLong
特点:
-
基于CAS(Compare-And-Swap)操作实现的原子性long值
-
提供原子性的读-改-写操作
-
适用于低到中等程度的并发更新
主要方法:
-
get()
,set()
-
getAndIncrement()
,incrementAndGet()
-
getAndAdd()
,addAndGet()
-
compareAndSet()
使用场景:
-
计数器
-
序列号生成
-
需要原子性更新的简单long值
替代方案:
-
高并发场景下可用LongAdder替代
2. AtomicLongArray
特点:
-
原子性long数组
-
可以对数组元素进行原子性操作
-
每个元素都像AtomicLong一样操作
主要方法:
-
类似AtomicLong,但针对数组元素
-
get(int i)
,set(int i, long newValue)
-
getAndAdd(int i, long delta)
使用场景:
-
需要原子性操作的long数组
-
并行算法中的数组元素更新
替代方案:
-
如果不需要数组操作,使用AtomicLong
-
高并发场景可考虑使用LongAdder数组(但需自行管理同步)
3. AtomicLongFieldUpdater
特点:
-
基于反射的实用工具,可以对指定类的指定volatile long字段进行原子更新
-
避免了将字段包装在AtomicLong中的内存开销
-
使用相对复杂
主要方法:
-
newUpdater(Class<U> tclass, String fieldName)
-
get()
,set()
-
getAndIncrement()
,getAndAdd()
使用场景:
-
需要原子性更新已有类的long字段
-
内存敏感的场景(避免创建AtomicLong对象)
替代方案:
-
如果可以修改类,直接使用AtomicLong字段
-
高并发场景不适用
4. LongAccumulator
特点:
-
比AtomicLong更通用的累加器
-
可以自定义累加函数
-
在高竞争下表现优于AtomicLong
-
内部使用类似LongAdder的分段设计
主要方法:
-
accumulate(long x)
-
get()
-
reset()
使用场景:
-
需要自定义累加逻辑(如最大值、最小值等)
-
高并发的统计、聚合操作
替代方案:
-
简单累加可用LongAdder
-
低并发场景可用AtomicLong
5. LongAdder
特点:
-
专为高并发场景设计
-
使用分段累加策略减少竞争
-
在sum()时才合并结果
-
比AtomicLong有更好的写吞吐量
主要方法:
-
add(long x)
-
increment()
,decrement()
-
sum()
(注意: 不是原子快照)
使用场景:
-
高并发计数器(如统计、度量)
-
不要求实时精确值的场景
替代方案:
-
低并发场景可用AtomicLong
-
需要自定义累加逻辑用LongAccumulator
对比总结
特性 | AtomicLong | AtomicLongArray | AtomicLongFieldUpdater | LongAccumulator | LongAdder |
---|---|---|---|---|---|
基本功能 | 原子long | 原子long数组 | 原子更新对象字段 | 可自定义累加器 | 高并发累加器 |
高并发性能 | 一般 | 一般 | 一般 | 优秀 | 极佳 |
内存开销 | 低 | 中 | 极低(利用现有字段) | 中 | 中 |
适用场景 | 通用计数器 | 原子数组操作 | 已有类字段原子更新 | 自定义聚合 | 高并发计数 |
精确性 | 精确 | 精确 | 精确 | 最终精确 | 最终一致 |
替代方案 | LongAdder | - | AtomicLong | LongAdder | AtomicLong |
选择建议
-
低并发简单计数:AtomicLong
-
高并发计数:LongAdder
-
自定义聚合函数:LongAccumulator
-
原子数组操作:AtomicLongArray
-
已有类字段原子更新:AtomicLongFieldUpdater