ConcurrentHashMap Internals
Master Java's most important concurrent collection. Understand how ConcurrentHashMap evolved from segment-based locking to CAS operations, why it dramatically outperforms synchronized maps, and how to use it correctly for thread-safe operations.
π At a Glance
| Aspect | Details |
|---|---|
| Topic | ConcurrentHashMap, concurrent operations, thread safety |
| Complexity | Advanced |
| Prerequisites | Part 12 (HashMap Internals), basic concurrency knowledge |
| Time to Master | 4-5 hours |
| Interview Frequency | Very High (thread safety, CAS operations, compound actions) |
π― What You'll Learn
After completing this article, you will be able to:
- Understand ConcurrentHashMap's lock-free read operations
- Master the evolution from Java 7 segments to Java 8+ CAS
- Use atomic compound operations (compute, merge) correctly
- Avoid common concurrency pitfalls with ConcurrentHashMap
- Choose between ConcurrentHashMap and synchronized alternatives
Interactive Visualizer
Watch how ConcurrentHashMap handles concurrent access with segment-level locking - multiple threads can write to different segments simultaneously:
Loading visualizer...
Production Story: The HashMap Race Condition Disaster
The Incident
Our session management service was corrupting user data in production. Users were being logged into wrong accounts, seeing other users' data, and experiencing random authentication failures.
JAVA(16 lines)CodeLoading syntax highlighter...
The Race Condition
TEXT(15 lines)CodeLoading syntax highlighter...
The ConcurrentHashMap Fix
JAVA(21 lines)CodeLoading syntax highlighter...
Performance Comparison
JAVA(11 lines)CodeLoading syntax highlighter...
Why ConcurrentHashMap is Faster
- Lock-free reads: get() uses volatile reads, no locking
- Per-bin locking: Only lock the specific bucket, not entire map
- CAS operations: Atomic updates without locks when possible
- Optimistic concurrency: Assume success, handle conflicts
Mental Model: The Restaurant Kitchen
TEXT(28 lines)CodeLoading syntax highlighter...
Deep Dive: Evolution of ConcurrentHashMap
Java 7: Segment-Based Locking
JAVA(14 lines)CodeLoading syntax highlighter...
Java 8+: CAS + Per-Bin Locking
JAVA(11 lines)CodeLoading syntax highlighter...
Java 8+ Key Improvements
TEXT(19 lines)CodeLoading syntax highlighter...
Deep Dive: ConcurrentHashMap Operations
Basic Thread-Safe Operations
JAVA(18 lines)CodeLoading syntax highlighter...
Atomic Compound Operations (Java 8+)
JAVA(19 lines)CodeLoading syntax highlighter...
Bulk Operations (Java 8+)
JAVA(24 lines)CodeLoading syntax highlighter...
Deep Dive: Internal Operations
CAS (Compare-And-Swap)
JAVA(16 lines)CodeLoading syntax highlighter...
Lock-Free Read
JAVA(24 lines)CodeLoading syntax highlighter...
Concurrent Resize
JAVA(13 lines)CodeLoading syntax highlighter...
Deep Dive: Common Patterns
Pattern 1: Concurrent Counter
JAVA(15 lines)CodeLoading syntax highlighter...
Pattern 2: Cache with Expiration
JAVA(41 lines)CodeLoading syntax highlighter...
Pattern 3: Concurrent Set
JAVA(9 lines)CodeLoading syntax highlighter...
Pattern 4: Memoization
JAVA(18 lines)CodeLoading syntax highlighter...
Deep Dive: Weakly Consistent Iterators
Iterator Behavior
JAVA(17 lines)CodeLoading syntax highlighter...
Implications
JAVA(12 lines)CodeLoading syntax highlighter...
β οΈ Common Mistakes
Mistake 1: Non-Atomic Check-Then-Act
JAVA(14 lines)CodeLoading syntax highlighter...
Mistake 2: Modifying Map in computeIfAbsent
JAVA(11 lines)CodeLoading syntax highlighter...
Mistake 3: Assuming size() is Accurate
JAVA(13 lines)CodeLoading syntax highlighter...
Mistake 4: Using null Keys or Values
JAVA(10 lines)CodeLoading syntax highlighter...
Mistake 5: Replacing with Collections.synchronizedMap
JAVA(12 lines)CodeLoading syntax highlighter...
π Debug This
Challenge 1: The Lost Updates
JAVA(15 lines)CodeLoading syntax highlighter...
The get-then-put is not atomic. Multiple threads read the same value, all increment to the same result, losing updates.
JAVA(2 lines)CodeLoading syntax highlighter...
Challenge 2: The Deadlock
JAVA(5 lines)CodeLoading syntax highlighter...
In Java 8, nested computeIfAbsent on the same map can deadlock if both keys hash to the same bin (which gets locked).
In Java 9+, ConcurrentHashMap detects recursive compute and throws IllegalStateException.
Challenge 3: The Inconsistent View
JAVA(10 lines)CodeLoading syntax highlighter...
- If iterator doesn't see "C": sum = 1 + 2 = 3
- If iterator sees "C": sum = 1 + 2 + 3 = 6
The iterator is weakly consistent - it may or may not see concurrent modifications.
π» Exercises
Exercise 1: Thread-Safe Counter Map
Implement a thread-safe word counter:
JAVA(5 lines)CodeLoading syntax highlighter...
JAVA(18 lines)CodeLoading syntax highlighter...
Exercise 2: Concurrent Cache with Loading
Implement a cache that loads values on cache miss:
JAVA(6 lines)CodeLoading syntax highlighter...
JAVA(24 lines)CodeLoading syntax highlighter...
Exercise 3: Rate Limiter
Implement a thread-safe rate limiter:
JAVA(4 lines)CodeLoading syntax highlighter...
JAVA(40 lines)CodeLoading syntax highlighter...
π€ Senior-Level Interview Questions
Question 1: HashMap vs ConcurrentHashMap Thread Safety
HashMap issues under concurrency:
- Lost updates: Two threads read same value, both write β one lost
- Infinite loop: Resize during concurrent insert β circular linked list
- Corrupted data: Partial writes visible to other threads
- Null returns: Entry in wrong bucket after concurrent resize
JAVA(5 lines)CodeLoading syntax highlighter...
Question 2: CAS vs Locking
- Adding first node to empty bin
- Updating single values atomically
- Size counting (using LongAdder internally)
- Adding to non-empty bin (collision handling)
- Tree operations (when bin is TreeBin)
- Resize operations
JAVA(8 lines)CodeLoading syntax highlighter...
Question 3: Weakly Consistent Semantics
Guarantees:
- No ConcurrentModificationException
- Elements returned at most once
- Elements present for entire iteration will be seen
No guarantees:
- Seeing modifications during iteration
- Consistent snapshot of all elements
- Specific ordering
JAVA(6 lines)CodeLoading syntax highlighter...
Question 4: computeIfAbsent vs putIfAbsent
JAVA(17 lines)CodeLoading syntax highlighter...
Question 5: Concurrent Resize
- ForwardingNode marker: Indicates "look in new table"
- Work stealing: Multiple threads help transfer bins
- Gradual transfer: Bins transferred incrementally
- Read during resize: Reads check both tables
JAVA(5 lines)CodeLoading syntax highlighter...
Question 6: size() vs mappingCount()
JAVA(12 lines)CodeLoading syntax highlighter...
π Summary & Key Takeaways
Thread Safety Evolution
- Java 7: Segment-based locking (16 segments default)
- Java 8+: Per-bin locking + CAS operations
- Lock-free reads, fine-grained write locking
Key Operations
- get(), containsKey(): Lock-free (volatile reads)
- put(), remove(): CAS for empty bins, synchronized for collisions
- computeIfAbsent(), merge(): Atomic compound operations
Common Patterns
- Counter: merge() or LongAdder for high contention
- Cache: computeIfAbsent() for lazy loading
- Set: ConcurrentHashMap.newKeySet()
Pitfalls to Avoid
- Don't use check-then-act (not atomic)
- Don't modify map inside compute functions
- Don't rely on size() for logic
- Don't use null keys or values
π Conclusion
ConcurrentHashMap is the backbone of concurrent Java applications. Its evolution from segment-based locking to CAS operations demonstrates sophisticated engineering for scalable concurrency. Understanding its internals helps you use it correctly and avoid subtle bugs.
Key takeaways:
- Lock-free reads make ConcurrentHashMap extremely fast for read-heavy workloads
- Atomic operations (compute, merge) prevent race conditions
- Never use check-then-act patterns - use atomic operations instead
- Iterators are weakly consistent - may or may not see concurrent modifications
- Don't modify map inside compute - can cause deadlock
In the next article, we'll explore ConcurrentHashMap's advanced features including bulk operations, custom reductions, and integration with parallel streams.
π Review Schedule
To solidify your understanding, review this material:
- Tomorrow: Practice atomic operations (compute, merge)
- In 3 days: Implement concurrent counter pattern
- In 1 week: Explain CAS vs locking to a colleague
- In 2 weeks: Review all pitfalls and common mistakes