文章目录

Java LongAdder的base与cells数组的求和逻辑

发布于 2026-05-09 10:20:50 · 浏览 13 次 · 评论 0 条

Java LongAdder的base与cells数组的求和逻辑

Java并发包中的LongAdder类用于在高并发场景下高效地实现计数功能。其核心机制依赖于两个关键部分:base字段和cells数组。理解它们的求和逻辑对于掌握LongAdder的工作原理至关重要。

1. LongAdder的结构

LongAdder继承自Striped64类,内部维护两个主要成员:

  • base:一个volatile long类型的变量,用于存储低竞争情况下的计数值。
  • cells:一个Striped64.Cell类型的数组,用于存储高竞争情况下的分片计数值。

Striped64.CellStriped64的内部类,包含一个volatile long value字段,用于存储每个分片的计数值。

2. base字段的作用

base字段是LongAdder的初始计数值存储位置。当并发程度较低时,所有更新操作都会直接操作base字段,避免创建cells数组带来的额外开销。

3. cells数组的作用

当并发程度较高时,LongAdder会创建cells数组,将计数值分散到不同的分片中。每个线程会根据其哈希码选择一个Cell进行更新,从而减少竞争。

4. 求和逻辑的详细步骤

当调用LongAddersum()方法获取当前总和时,会执行以下步骤:

4.1 读取base值

获取当前总和时,首先读取base字段的值。由于basevolatile类型,读取操作具有可见性保证。

long b = base;

4.2 检查cells数组是否存在

判断cells数组是否为空。如果数组为空,说明没有并发竞争,直接返回base的值。

if (cells == null)
    return b;

4.3 遍历cells数组

如果cells数组不为空,遍历数组中的每个Cell元素,将每个Cellvalue字段值累加到总和上。

long sum = b;
Striped64.Cell[] cs = cells;
for (int i = 0; i < cs.length; ++i) {
    long v = cs[i].value;
    sum += v;
}

4.4 返回总和

返回累加后的总和值,即base的值加上所有Cellvalue值之和。

return sum;

5. 并发场景下的求和处理

在并发更新过程中,cells数组可能被动态扩容。求和操作会读取cells数组的当前状态,即使此时有其他线程在修改cells数组或其中的Cell值,volatile保证的可见性确保求和操作能够获取到相对一致的结果。

6. 示例代码

以下是一个简化的sum()方法实现,展示了上述求和逻辑:

public long sum() {
    long sum = base;
    Striped64.Cell[] cs = cells;
    if (cs != null) {
        for (int i = 0; i < cs.length; ++i) {
            long v = cs[i].value;
            sum += v;
        }
    }
    return sum;
}

通过上述步骤,LongAdder能够在高并发环境下高效地计算计数值的总和,同时通过basecells的协同工作,平衡了低竞争和高竞争场景下的性能需求。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文