ConcurrentHashMap.computeIfAbsent establishes a value for one absent key atomically; a LongAdder can then absorb frequent updates to that key without replacing a boxed count on every increment.
Java ConcurrentHashMap.computeIfAbsent: create a counter once per key
Operational contract
This counter registry creates an adder only when a depot key is absent. The mapping callback only constructs the value: it does no I/O, no recursive map update, and no work that can wait for another mapping. A null result would leave the key absent, but this callback always returns an adder. The increment occurs after the mapping operation. The map therefore guarantees safe installation, while the adder owns the separate count update. Keep depot identifiers bounded or evict stale keys under an explicit retention policy; a concurrent map does not limit its own key population.
Failure case
Forty-seven request workers record a new depot at the same time. They may race to reach computeIfAbsent, yet every successful call obtains the installed counter for that key and increments it. A dashboard that reads several depot sums while requests continue still observes a moving aggregate, not one transaction across depots.
Java code
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
public class DepotArrivalCounters {
private final ConcurrentHashMap<String, LongAdder> arrivals = new ConcurrentHashMap<>();
public void record(String depotId) {
arrivals.computeIfAbsent(depotId, ignoredDepot -> new LongAdder()).increment();
}
public long count(String depotId) {
LongAdder counter = arrivals.get(depotId);
return counter == null ? 0 : counter.sum();
}
}Performance and ownership cost
Expected key lookup is near O(1) with normal hashing, but contention and collision structure affect latency. Memory is O(K) for K retained depot keys plus adder cells created under contention. sum reads concurrent cells and is not an atomic snapshot with updates or other keys.
Common Mistakes
- Do not perform remote work or update the same map inside the mapping callback.
- Do not use a LongAdder sum as an exact multi-key accounting snapshot.
- Do not let untrusted key cardinality grow without a retention rule.
Connected lessons
- Java ConcurrentHashMap.compute: serialize one key's remapping
- Java LongAdder: striped counters and the limits of sum snapshots
- Java ConcurrentHashMap: atomic updates and weakly consistent reads
- Java ConcurrentSkipListMap: inspect an ordered time window
- Java CopyOnWriteArrayList: dispatch against a listener snapshot
- Java AtomicReference: publish one immutable map snapshot
- Java concurrent state and handoff quiz
- Advanced Java
