Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java ConcurrentHashMap.compute: serialize one key’s remapping

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

ConcurrentHashMap.compute applies a remapping for one key atomically, so concurrent callers can update that key without a separate get-then-put race.

Keep the mapping function bounded

Two workers call compute for the same shipment key. Each sees the current value supplied by the map, and the final count is two regardless of which worker arrived first. A separate get followed by put could lose one increment.

The map may block other updates to the same key while the remapping function runs. Do not perform remote I/O or recursively update the same map from inside it. Concurrent map contracts cover key-level ownership; Map.merge has its own null-removal behavior.

Do not confuse key atomicity with transactions

A compute call protects one key's remapping. Updating a second map, writing a database row, or publishing an event remains outside that atomic boundary. If those effects must succeed together, use a higher-level transaction or explicit recovery protocol.

Working program

Java
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

public class ShipmentAttemptTally {
    public static void main(String[] args) throws InterruptedException {
        ConcurrentHashMap<String, Integer> counts = new ConcurrentHashMap<>();
        CountDownLatch begin = new CountDownLatch(1);
        Runnable record = () -> {
            try { begin.await(); }
            catch (InterruptedException stopped) { Thread.currentThread().interrupt(); return; }
            counts.compute("lot-47", (key, previous) -> previous == null ? 1 : previous + 1);
        };
        Thread first = new Thread(record);
        Thread second = new Thread(record);
        first.start();
        second.start();
        begin.countDown();
        first.join();
        second.join();
        System.out.println("attempts=" + counts.get("lot-47"));
    }
}

Output

Output
attempts=2

Cost and ownership

The fixture uses one map entry and two threads. A short remapping function performs constant application work per call, while contention on a hot key can serialize callers. The map does not make external effects atomic with its value.

Common Mistakes

  • Do not replace compute with get followed by put for a contended counter.
  • Do not block on remote work inside the remapping function.
  • Do not assume one-key atomicity covers a database write or a second key.

Read next

Java ConcurrentHashMap: atomic updates and weakly consistent reads, Java Map.merge: combine a value or remove its mapping, Java volatile counter: visible writes can still lose an update, Java atomic variables: compare-and-set and one-variable invariants.

java
concurrency
concurrenthashmap-compute-contention
Storage details