Skip to content

LongAdder and DoubleAdder

LongAdder and DoubleAdder are concurrent utility classes introduced in Java 8 within the java.lang package.^[600-developer__java__java-base__java-Runtime-Number.md] They are part of the Striped64 family of concurrent components, which are designed to operate in a lock-free and thread-safe manner under high contention.^[600-developer__java__java-base__java-Runtime-Number.md]

Overview

Unlike atomic classes like AtomicLong which rely on a single volatile variable subject to contention (CAS loops), LongAdder and DoubleAdder maintain a set of variables internally to reduce contention and improve throughput.^[600-developer__java__java-base__java-Runtime-Number.md] The Striped64 mechanism allows these classes to distribute updates across multiple cells, summing them only when a total value is required.^[600-developer__java__java-base__java-Runtime-Number.md]

Relationship to LongAccumulator

These classes are specialized or simplified forms of the LongAccumulator and DoubleAccumulator classes.^[600-developer__java__java-base__java-Runtime-Number.md]

  • LongAdder: The instantiation new [LongAdder](<./longadder.md>)() is functionally equivalent to new [LongAccumulator](<./longaccumulator.md>)((x, y) -> x + y, 0L).^[600-developer__java__java-base__java-Runtime-Number.md]
  • DoubleAdder: The instantiation new DoubleAdder() is functionally equivalent to new DoubleAccumulator((x, y) -> x + y, 0.0).^[600-developer__java__java-base__java-Runtime-Number.md]

This indicates that LongAdder and DoubleAdder are specifically optimized for accumulation (summation) operations, whereas the Accumulator variants allow for custom associative functions.

Example Usage

The following example demonstrates the use of LongAdder in a concurrent environment with a thread pool.^[600-developer__java__java-base__java-Runtime-Number.md]

[LongAdder](<./longadder.md>) counter = new [LongAdder](<./longadder.md>)();
ExecutorService executorService = Executors.newFixedThreadPool(8);

int numberOfThreads = 4;
int numberOfIncrements = 100;

Runnable incrementAction = () -> IntStream
  .range(0, numberOfIncrements)
  .forEach(i -> counter.increment());

for (int i = 0; i < numberOfThreads; i++) {
    executorService.execute(incrementAction);
}

Sources

^[600-developer__java__java-base__java-Runtime-Number.md]