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 tonew [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 tonew 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);
}
Related Concepts¶
- [[Concurrency]]
- [[AtomicInteger]]
- LongAccumulator
- Striped64
Sources¶
^[600-developer__java__java-base__java-Runtime-Number.md]