Interview Prep Zoneby CuriouserLabs

Question 4 of 5 · staff level

ConcurrentHashMap vs Collections.synchronizedMap vs Hashtable. How does CHM achieve its scalability?

🎤 Say this first

Hashtable/synchronizedMap serialize every operation on one lock — correct but unscalable, and compound actions still need external locking. ConcurrentHashMap (Java 8+) uses lock-free reads (volatile bucket access) and per-bin locking via CAS + synchronized on the first node of a bucket, so writers to different buckets don't contend. It also offers atomic compound ops (computeIfAbsent, merge) and weakly-consistent iterators that never throw ConcurrentModificationException.

The full picture

  • Reads: no locking at all — volatile semantics on the table plus immutable-ish nodes make gets wait-free in the common case.
  • Writes: CAS the bucket head for empty bins; otherwise lock only that bin. Resizing is cooperative — multiple threads help transfer bins.
  • Compound atomicity: computeIfAbsent(k, f) is atomic per key — but the mapping function must be short and must not touch other keys (risk of deadlock/livelock).
  • Iteration: weakly consistent — reflects some state since creation, never throws CME; contrast with synchronizedMap, where you must manually synchronize the whole iteration.
  • No null keys/values — by design: a null get() would be ambiguous (absent vs mapped-to-null) without locking to check.

🔄 Likely follow-up questions

  • When would ConcurrentSkipListMap be the right choice? (concurrent + sorted / range queries)
  • How would you build a thread-safe multi-map or a cache with TTL? (Caffeine, not DIY)
  • Why did segment-based locking (Java 7 CHM) get replaced?