Skip to main content
  1. Java Concurrency (java.util.concurrent)/

ConcurrentMap Interface

2 mins

ConcurrentMap extends the standard Map interface to provide several atomic operations that are essential for thread-safe map manipulation without external synchronization.

Source Code #

View Source on GitHub

Atomic Operations #

The interface defines several key methods that are guaranteed to be atomic:

public interface ConcurrentMap<K, V> extends Map<K, V> {
    // Replaces the entry for a key only if currently mapped to a given value.
    boolean replace(K key, V oldValue, V newValue);

    // Replaces the entry for a key only if currently mapped to some value.
    V replace(K key, V value);

    // If the specified key is not already associated with a value, associates it with the given value.
    V putIfAbsent(K key, V value);

    // Removes the entry for a key only if currently mapped to a given value.
    boolean remove(Object key, Object value);
}

Canonical Usage #

When to use: Use ConcurrentMap whenever you need to perform “check-then-act” operations on a map across multiple threads. It prevents race conditions between checking if a key exists and putting a new value.

Common Patterns:

  • Memoization: Using putIfAbsent to cache the results of expensive computations.
  • Atomic Counters: Using replace(key, old, new) to increment a value safely.
ConcurrentMap<String, String> cache = new ConcurrentHashMap<>();

// Memoization pattern
public String getOrCompute(String key) {
    String val = cache.get(key);
    if (val == null) {
        val = computeExpensiveValue(key);
        String existing = cache.putIfAbsent(key, val);
        if (existing != null) val = existing; // Use the one put by another thread
    }
    return val;
}