LongAdder 如何在高并发下用 CAS 实现比 AtomicInteger 更高性能?
                           
天天向上
发布: 2025-07-12 13:25:11

原创
620 人浏览过

这是一个非常典型也非常重要的并发性能优化问题。


1、简要结论:

LongAdderAtomicLong 的性能增强版,在高并发场景下比 AtomicLong 更高效,其核心是:使用分段(Striped)思想 + CAS 操作,避免大量线程争抢同一个变量。


2、为什么 AtomicLong 会成为性能瓶颈?

AtomicLong 的底层实现是基于 CAS(Compare-And-Swap) 的:

public final long incrementAndGet() {
    for (;;) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

⚠️ 问题:

  • 所有线程都在争抢一个变量(如 count
  • 并发高时,CAS 成功率变低,大量自旋,CPU 开销大

3、LongAdder 的设计核心:分段计数

👉 类似“分区统计”:把一个变量拆成多个,分摊竞争压力

+-----------+-----------+-----------+-----------+
| Cell[0]   | Cell[1]   | Cell[2]   | ...       |
|   5       |   3       |   4       |           |
+-----------+-----------+-----------+-----------+
  • 每个线程对不同的 Cell 操作
  • 最后通过所有 Cell 的值 + 基础值(base)求和得出总值

4、源码结构(简化)

public class LongAdder extends Striped64 {
    // 分段数组(懒初始化)
    transient volatile Cell[] cells;

    // 低竞争时使用的基础值
    transient volatile long base;
}

5、increment() 方法实现逻辑(简化)

public void increment() {
    Cell[] as; long b; int m, h;
    if ((as = cells) != null || !casBase(b = base, b + 1)) {
        boolean uncontended = true;
        if (as == null || (m = as.length - 1) < 0 ||
            as[h & m] == null || !(uncontended = as[h & m].cas(v, v + 1)))
            longAccumulate(1L, null, uncontended);
    }
}

⛓️ 解释流程:

  1. 优先尝试 CAS 增加 base(低并发下走这里)
  2. 如果失败,尝试对当前线程的 Cell 位置进行 CAS 增加
  3. 如果还失败,说明竞争严重,调用 longAccumulate()
  • 初始化或扩展 cells 数组
  • 重试插入到新的 Cell 槽位

6、求和操作(sum())

public long sum() {
    Cell[] as = cells;
    long sum = base;
    if (as != null) {
        for (Cell a : as) {
            if (a != null)
                sum += a.value;
        }
    }
    return sum;
}

⚠️ sum() 不是原子操作,仅做近似统计(适用于统计计数、QPS、请求量等)


7、LongAdder vs AtomicLong 性能对比

指标AtomicLongLongAdder
CAS 重试开销高(集中在单变量)低(分段分散)
高并发性能一般,容易争抢优秀,避免热点竞争
空间开销稍高(多个 Cell 占内存)
精度精确高并发下可能近似(非原子)
适用场景低并发/精准计数高并发/统计型计数(QPS)

8、实际使用建议

应用场景推荐使用
Web 访问计数器LongAdder(吞吐量更高)
并发限流统计LongAdder
交易系统计数(需精确)❌ 用 AtomicLong 或加锁
计量指标上报(Prometheus)LongAdder

9、参考链接


10、总结记忆口诀

AtomicLong 高竞争易瓶颈,LongAdder 分段巧避锋;base 优先,cell 分摊,近似统计快如风。


更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *