</>

Technology

Core Java

Difficulty

Advanced

Interview Question

How does ConcurrentHashMap work in Java? How is it different from HashMap and Hashtable?

Answer

ConcurrentHashMap vs HashMap vs Hashtable

Quick Comparison

FeatureHashMapHashtableConcurrentHashMap
Thread-safeNoYes (full lock)Yes (partial lock)
PerformanceFastSlow (lock on all ops)High concurrency
Null keys1 allowedNot allowedNot allowed
Null valuesAllowedNot allowedNot allowed
SynchronizedNoEvery methodBucket/node level
Java version1.21.0 (legacy)1.5 (java.util.concurrent)

HashMap — Not Thread-Safe

Java
Map<String, Integer> map = new HashMap<>();

// Two threads writing simultaneously → data corruption, infinite loop (Java 7)!
// Thread 1
map.put("Alice", 1);
// Thread 2 (at same time)
map.put("Bob", 2);
// Result: ConcurrentModificationException or data loss!

// Use only in single-threaded context
Map<String, Integer> local = new HashMap<>();  // safe in single thread

Hashtable — Fully Synchronized (Legacy, Avoid)

Java
Map<String, Integer> table = new Hashtable<>();

// Every method is synchronized — only one thread at a time
// Even reads block other reads!
table.put("Alice", 1);    // locks entire map
table.get("Alice");       // also locks entire map

// Problem: bottleneck in high-concurrency scenarios

ConcurrentHashMap — Fine-Grained Locking (Best Choice)

Java
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();

// Java 7: divided into 16 segments, each with own lock
// Java 8: CAS (Compare-And-Swap) operations at node level

// Safe for concurrent reads — no locking at all!
// Safe for concurrent writes — only locks the specific bucket

concurrentMap.put("Alice", 1);   // locks only Alice's bucket
concurrentMap.put("Bob", 2);     // locks only Bob's bucket — PARALLEL!

Atomic Operations in ConcurrentHashMap

Java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("counter", 0);

// putIfAbsent — atomic check-and-insert
map.putIfAbsent("newKey", 42);  // only puts if key doesn''t exist (atomic)

// computeIfAbsent — compute value if missing (atomic)
map.computeIfAbsent("user123", key -> loadFromDB(key));

// compute — atomic update
map.compute("counter", (k, v) -> v == null ? 1 : v + 1);  // atomic increment!

// merge — atomic merge with function
map.merge("counter", 1, Integer::sum);  // adds 1 to existing value

Producer-Consumer with ConcurrentHashMap

Java
ConcurrentHashMap<String, String> sessionCache = new ConcurrentHashMap<>();

// Thread 1 (writing sessions)
Thread writer = new Thread(() -> {
    for (int i = 0; i < 100; i++) {
        sessionCache.put("session-" + i, "user-" + i);
    }
});

// Thread 2 (reading sessions)
Thread reader = new Thread(() -> {
    sessionCache.forEach((sessionId, userId) ->
        System.out.println("Active: " + sessionId + " → " + userId));
});

writer.start();
reader.start();
// Safe! No ConcurrentModificationException

When to Use What

Java
// 1. Single thread — use HashMap (fastest)
Map<String, String> config = new HashMap<>();

// 2. Legacy code / simple sync — use Collections.synchronizedMap
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
// Still locks the whole map though

// 3. High concurrency reads + some writes — use ConcurrentHashMap
Map<String, UserSession> sessions = new ConcurrentHashMap<>();

// 4. NEVER use Hashtable in new code — it''s legacy

In Automation Testing (Parallel Tests)

Java
// Share test results across parallel test threads
public class TestResultStore {
    private static final ConcurrentHashMap<String, String> results =
        new ConcurrentHashMap<>();

    public static void record(String testName, String status) {
        results.put(testName, status);  // thread-safe across parallel tests
    }

    public static Map<String, String> getAll() {
        return Collections.unmodifiableMap(results);
    }

    public static long countPassed() {
        return results.values().stream().filter("PASSED"::equals).count();
    }
}

// In any test thread
TestResultStore.record(testName, "PASSED");

Follow AutomateQA

Related Topics