ConcurrentHashMap Compound Operations — Interview Questions
⚡ Short Answer
ConcurrentHashMap guarantees each individual method call (get, put, remove) is thread-safe — but a get() followed by a put() based on that result is two separate operations with a window between them where another thread can interleave, the same check-then-act race a plain HashMap has, just with a thread-safe map underneath it. computeIfAbsent(), compute(), and merge() close that window because the whole read-modify-write happens atomically under the map's internal per-bin lock, as a single operation.
☕Coffee Chat Question
Concept Made Simple
“ConcurrentHashMap is thread-safe — so why can a get-then-put sequence still race, and how do computeIfAbsent/merge fix it?”
🧠Mind Map Answer
Remember It Faster
'Thread-safe' on a ConcurrentHashMap means each *individual* method call is atomic and safely published across threads — it says nothing about a sequence of calls you compose yourself. if (!map.containsKey(k)) map.put(k, v) is exactly as racy as it would be on a plain HashMap; the map's internal safety doesn't extend across your own multi-statement logic.
Key takeaway: thread-safety is per-call, not per-transaction — any time your logic spans more than one map call, reach for the compound methods instead of composing get/put yourself.
⌨️Hands-on Keyboard
Learn by Doing
ConcurrentHashMap<String, List<String>> index = new ConcurrentHashMap<>();
// RACY: two threads can both see containsKey()==false and both create a new list
if (!index.containsKey(key)) {
index.put(key, new ArrayList<>());
}
index.get(key).add(value); // also unsafe if the List itself isn't thread-safe
// CORRECT: atomic check-and-insert, single operation
index.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>()).add(value);🔥What If?
Think Beyond the Expected
What happens if the mapping function passed to computeIfAbsent() is slow or tries to modify the same map?
It runs while the map holds a lock on that key's bin, so a slow function blocks other threads touching keys in the same bin. Modifying the same map from inside its own mapping function is not a safe, supported pattern — the JDK documents this as unsupported, and doesn't guarantee what happens: depending on the exact operation it can manifest as blocked/hung threads, an exception, or other incorrect behavior. The rule to follow isn't 'expect exception X' — it's simply: never touch the same map from within its own mapping function.
😂Real World
This is the classic 'we used ConcurrentHashMap so it must be safe' bug — a caching layer built on get()-then-put() under load creates duplicate cache entries or, worse, wraps the value in a non-thread-safe collection (a plain ArrayList) that then corrupts under concurrent add() calls even though the outer map was never the problem.
🗣️Real Talk from Guru
In an interview I'd say: swapping HashMap for ConcurrentHashMap fixes the map's internal safety, but it doesn't automatically fix your algorithm — if your logic reads then writes based on that read, you need computeIfAbsent/merge/compute, full stop.
🎯Interviewer's Expectation
Keywords they're listening for:
⚠️Common Mistakes
- ✗Composing get()/containsKey() and put() as if the sequence were atomic
- ✗Storing a non-thread-safe collection as the map's value
- ✗Writing slow or map-mutating logic inside a mapping function
✅Best Practices
- ✓Use computeIfAbsent/compute/merge for any read-modify-write on a shared map
- ✓Keep mapping functions fast and free of side effects on the same map
- ✓Pair with a thread-safe value type (CopyOnWriteArrayList, another ConcurrentHashMap) when needed
🔁Follow-up Questions
- 1What's the difference between compute() and computeIfAbsent()?
- 2Why must the value type stored (e.g. a List) also be thread-safe on its own?
- 3What happens if two threads call computeIfAbsent() with the same key simultaneously?
🧩Related Technologies
Continue Learning with AI
Take this question deeper with your favourite AI assistant. Pick a depth, copy the prompt, or open it directly — AI is your learning companion, not a shortcut.
Plain-language foundations
I'm preparing for a software engineering interview and want to understand this from scratch, as a beginner. Topic: ConcurrentHashMap (Java Collections) Interview question: "ConcurrentHashMap is thread-safe — so why can a get-then-put sequence still race, and how do computeIfAbsent/merge fix it?" Please: 1. Explain the core idea in simple, plain language, using an everyday analogy. 2. Define any technical terms you use. 3. Walk through one small, concrete example. 4. Finish with a single sentence I can easily remember. Keep the tone friendly and assume I'm new to this topic.
Was this answer helpful?
⭐ Featured Products
Support our platform by exploring our recommended products.
As an Amazon affiliate, purchases through these links may earn us a small commission — at no extra cost to you. It helps keep Full Stack Interview Guru free.