返回

揭秘 Java 并发编程中的 LongAdder 源码,深入理解并发控制

后端

Java 并发编程之 LongAdder 源码解读(一)

在 Java 并发编程中,LongAdder 扮演着至关重要的角色,它能高效地管理并发场景中的长整型累加操作。为了深入理解其工作原理,让我们踏入其源码的海洋,逐行剖析它的奥秘。

引言

上一篇文章中,我们领略了 LongAdder 常用的方法。今天,让我们以源码为指南,踏上一次探索之旅,揭开 LongAdder 的底层实现。

LongAdder 的基本实现

LongAdder 的核心是一个 Cell 数组,它是一个具有长度的数组,其中每个元素都是一个 Cell 对象。每个 Cell 存储一个 long 型值,并提供一系列方法来对其进行原子更新。

当对一个长整型值进行累加操作时,LongAdder 会选择一个适当的 Cell 来进行操作。这个 Cell 的选择基于当前线程的 ThreadLocalRandom 产生的伪随机值。这种选择策略有助于分散并发负载,避免热点问题。

代码分析

public class LongAdder {

    private static final int NCPU = Runtime.getRuntime().availableProcessors();
    private static final long serialVersionUID = 7249069246763182397L;
    private final Cell[] cells;
    private transient ThreadLocal<Cell> tlc;

    public LongAdder() {
        this(NCPU);
    }

    public LongAdder(int n) {
        cells = new Cell[n > 0 ? n : 1];
    }

    final Cell getCell(int n) {
        return (n >= cells.length || cells[n] == null) ? cells[n = ThreadLocalRandom.getProbe()] : cells[n];
    }

    public void add(long x) {
        Cell[] as;
        long b, v;
        int n;
        if ((as = cells) != null || !compareAndSwapState(0L, x)) {
            Cell a;
            int m = as.length - 1 & n = (int)x == 0L ? NCPU : ThreadLocalRandom.getProbe();
            if ((a = as[n]) == null || !(v = a.value) == 0L && compareAndSwapValue(a, v, v + x)) {
                return;
            }
            b = sum();
            long u = (x <= 0L && b - x < 0L) ? (long)Long.MAX_VALUE : (long)Long.MIN_VALUE;
            if (compareAndSwapState(b, u)) {
                as[n] = new Cell(x);
            }
        }
    }

    ... // 省略其他方法

}

总结

本文对 LongAdder 的基本实现进行了分析。我们了解到 LongAdder 使用 Cell 数组来存储值,并通过伪随机选择策略来平衡并发负载。通过深入理解 LongAdder 的源码,我们可以更全面地掌握其工作原理,从而在实际并发编程中更好地利用其特性。