An AtomicReference can publish one immutable aggregate map as a unit. Readers obtain a coherent version without coordinating each key separately.
Java AtomicReference: publish one immutable map snapshot
Operational contract
The publisher copies the current map, changes one depot balance, then installs an immutable replacement through updateAndGet. The lambda may run more than once after contention, so it contains only pure in-memory construction; never send an invoice or write a database row there. Map.copyOf rejects null keys and values. Every snapshot returned to a reader is one published version, although the reader can become stale immediately after fetching it. This fits a small, rarely updated configuration or report map rather than a high-volume counter.
Failure case
A pricing page must show one internally consistent set of 47 depot fees. A reader obtains one map reference and uses all its entries. Concurrent publication cannot change that map under the reader's feet. If fees are updated constantly, copying the whole map on each update becomes expensive.
Java code
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public class DepotFeeSnapshots {
private final AtomicReference<Map<String, Long>> published =
new AtomicReference<>(Map.of());
public void setFee(String depotId, long feeCents) {
if (feeCents < 0) throw new IllegalArgumentException("Negative fee");
published.updateAndGet(previous -> {
Map<String, Long> next = new HashMap<>(previous);
next.put(depotId, feeCents);
if (next.size() > 47) throw new IllegalStateException("Too many depots");
return Map.copyOf(next);
});
}
public Map<String, Long> snapshot() {
return published.get();
}
}Performance and ownership cost
A read is O(1) to obtain a reference. Each update copies O(K) entries and allocates O(K) memory for K keys; contention can repeat that work before a successful compare-and-set. The 47-key cap keeps that cost deliberate.
Common Mistakes
- Do not put side effects in an update lambda that may be retried.
- Do not mutate a previously published map after publication.
- Do not equate one immutable in-memory version with a durable database transaction.
Connected lessons
- Java atomic variables: compare-and-set and one-variable invariants
- Java ConcurrentHashMap: atomic updates and weakly consistent reads
- Java ConcurrentSkipListMap: inspect an ordered time window
- Java ConcurrentHashMap.computeIfAbsent: create a counter once per key
- Java CopyOnWriteArrayList: dispatch against a listener snapshot
- Java concurrent state and handoff quiz
- Advanced Java
