Skip to main content

ConcurrentHashMap's atomic compute family

advanced15 min readLesson 134 of 180

computeIfAbsent/merge/compute as single atomic check-then-act, and the callback rules.

ConcurrentHashMap is not a synchronized HashMap — it is a concurrent object with its own atomic compound operations. The ones professionals use:

map.computeIfAbsent(key, k -> expensive(k));   // atomic: at most once per key
map.compute(key, (k, v) -> mergeInto(v));       // atomic read-modify-write
map.merge(key, 1, Integer::sum);                // the frequency-counter idiom
map.putIfAbsent(key, seed);                     // initialize-once

compute-family callbacks run under the bin's lock — they must be short, and must not touch other keys of the same map (nested compute on the same key deadlocks; on other keys risks it).

Why not Collections.synchronizedMap? Because if (!map.containsKey(k)) map.put(k, v) is two atomic operations — the check and the act can interleave across threads. CHM's compute family makes the whole check-then-act one atomic operation. That is the difference between a class that is internally consistent and an algorithm that is externally correct.