ConcurrentHashMap
๐ Quick Reference
| Property | Value |
|---|---|
| Type | Thread-safe hash map |
| Get/Put | O(1) average, thread-safe |
| Concurrency | Lock striping (segments) |
| Null | Neither keys nor values can be null |
| Consistency | Weakly consistent iteration |
| Best For | Multi-threaded caching, shared state |
๐ฎ Interactive Visualizer
Watch how ConcurrentHashMap handles concurrent operations:
Loading visualizer...
- See multiple threads accessing different segments
- Watch lock acquisition on writes
- Observe lock-free reads
- Compare with synchronized HashMap bottleneck
๐ง Key Operations
Creating
JAVA(8 lines)CodeLoading syntax highlighter...
Basic Operations (Thread-Safe)
JAVA(13 lines)CodeLoading syntax highlighter...
Atomic Compound Operations
JAVA(14 lines)CodeLoading syntax highlighter...
Bulk Operations (Java 8+)
JAVA(13 lines)CodeLoading syntax highlighter...
๐ Complexity & Concurrency
| Operation | Time | Thread Safety |
|---|---|---|
get(key) | O(1) | Lock-free read |
put(key, val) | O(1) | Per-bucket lock |
remove(key) | O(1) | Per-bucket lock |
putIfAbsent | O(1) | Atomic |
compute* | O(1) | Atomic within bucket |
size() | O(n) | Approximate |
Lock Striping (Java 7)
Segments (each with own lock): [Segment 0] โ bucket โ bucket โ bucket [Segment 1] โ bucket โ bucket โ bucket [Segment 2] โ bucket โ bucket โ bucket ... Concurrent writes to different segments don't block each other.
Node-Level Locking (Java 8+)
Buckets (synchronized on first node): [0] โ Node โ Node โ Node โ lock on first node [1] โ Node โ Node โ separate lock [2] โ null โ no lock needed ... Finer-grained: lock per bucket, not segment.
โ When to Use ConcurrentHashMap
Good Use Cases
- Shared caches - read-heavy with occasional updates
- Counters/stats - atomic increment with merge()
- Concurrent config - shared configuration
- Thread-safe lookup - replace synchronized HashMap
Avoid When
- Single-threaded - HashMap is faster (no sync overhead)
- Need null keys/values - CHM prohibits nulls
- Need consistent iteration - iterator is weakly consistent
- Full atomicity needed - compound ops may need external sync
๐ ConcurrentHashMap vs Alternatives
| Feature | HashMap | Hashtable | synchronizedMap | ConcurrentHashMap |
|---|---|---|---|---|
| Thread-safe | No | Yes | Yes | Yes |
| Null keys | Yes | No | Yes | No |
| Lock scope | N/A | Entire map | Entire map | Per-bucket |
| Performance | Best | Poor | Poor | Good |
| Recommended | Single thread | Never | Rarely | Multi-thread |
JAVA(8 lines)CodeLoading syntax highlighter...
๐งฉ Common Patterns
Thread-Safe Counter
JAVA(8 lines)CodeLoading syntax highlighter...
Caching with computeIfAbsent
JAVA(7 lines)CodeLoading syntax highlighter...
Check-Then-Act (Atomically)
JAVA(10 lines)CodeLoading syntax highlighter...
โ ๏ธ Common Pitfalls
1. Using Null Keys/Values
JAVA(6 lines)CodeLoading syntax highlighter...
2. Non-Atomic Check-Then-Act
JAVA(7 lines)CodeLoading syntax highlighter...
3. Blocking in compute()
JAVA(8 lines)CodeLoading syntax highlighter...
4. Relying on size() for Exact Count
JAVA(8 lines)CodeLoading syntax highlighter...
5. Iterating with Modifications
JAVA(5 lines)CodeLoading syntax highlighter...
๐ค Interview Tips
"In Java 8+, it uses lock-free reads and synchronized blocks on individual buckets for writes. Each bucket's first node acts as a lock, allowing concurrent access to different buckets.
"Null would be ambiguous: does get() returning null mean "key not present" or "value is null"? HashMap uses containsKey() to distinguish, but that's not atomic in CHM.
"Iterators reflect the state of the map at some point during or after creation. They won't throw ConcurrentModificationException, but may or may not reflect concurrent updates.
"CHM allows concurrent reads without locking and uses fine-grained locks for writes (per-bucket). synchronizedMap locks the entire map for every operation, creating a bottleneck.
๐ Series Navigation
ConcurrentHashMap from @tomaszjarosz/react-visualizers