AtomicLong 比锁更适合计数,因其基于CAS实现无锁原子操作,避免阻塞和上下文切换;它提供incrementAndGet等原子方法,具备volatile内存语义,适用于读多写少的计数场景。

AtomicLong 能通过 CAS(Compare-And-Swap)机制实现无锁计数,在高并发场景下比 synchronized 或 ReentrantLock 更轻量、更高效。
为什么 AtomicLong 比锁更适合计数
普通 long 变量的自增(如 count++)本质是“读-改-写”三步操作,非原子;加锁虽能保证线程安全,但会带来阻塞和上下文切换开销。AtomicLong 利用 CPU 级 CAS 指令,在硬件层面保证更新原子性,失败时自动重试,避免了锁竞争。
- CAS 是乐观策略:假设没有冲突,只在真正冲突时重试
- 无对象监视器开销,不涉及线程挂起/唤醒
- 适合读多写少、更新粒度小(如计数器)的场景
基本用法:安全地递增、递减、设置值
常用方法都是原子的,无需额外同步:
-
incrementAndGet():原子 +1 并返回新值(最常用) -
getAndIncrement():返回旧值后再 +1 -
addAndGet(delta):加指定值并返回结果 -
compareAndSet(expected, updated):仅当当前值等于 expected 时才更新,可用于条件更新
示例:
立即学习“Java免费学习笔记(深入)”;
AtomicLong counter = new AtomicLong(0);long current = counter.incrementAndGet(); // 线程安全的 ++
注意内存可见性与性能边界
AtomicLong 自带 volatile 语义,所有读写都具有 happens-before 关系,变量修改对其他线程立即可见——这点和加 volatile 的 long 一样,但 volatile long 不支持原子自增,所以不能替代 AtomicLong。
- 不要用
get()+ 普通运算再set(),这会破坏原子性 - 超高并发下(如每秒百万级更新),CAS 可能频繁失败导致 CPU 空转,此时可考虑
LongAdder(JDK8+)作为替代,它通过分段累加降低竞争 - AtomicLong 适合全局唯一计数、请求总量统计等;若需复杂逻辑(如“先查再更新”且依赖中间状态),仍需锁或更高级并发结构
实际使用建议
- 声明为
private final AtomicLong,避免被意外替换 - 避免在循环中反复调用
get()判断条件后执行非原子操作,可能引发竞态 - 日志打点、接口调用量统计、限流器中的令牌计数等,是 AtomicLong 的典型适用场景
- 如果需要初始化为某个值(如从配置加载),用
new AtomicLong(initValue)即可



















