πΊ️ Java Maps Explained: HashMap vs Hashtable vs ConcurrentHashMap
Java provides several map implementations, but not all of them are suitable for multi-threaded environments. Choosing the wrong one can lead to performance bottlenecks, thread-safety issues, or even corrupted data. In this post, we’ll explore HashMap, Hashtable, and ConcurrentHashMap, explain when to use each, and dive into how ConcurrentHashMap works under the hood.
1. π️ HashMap
HashMap is the standard, non-thread-safe map in Java. Allows null keys/values and provides fast lookups (O(1) average).
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
Integer value = map.get("apple");
✅ Fast and memory-efficient for single-threaded applications
❌ Not thread-safe, requires external synchronization in multi-threaded code
2. π§± Hashtable
Hashtable is a legacy, thread-safe map. All methods are synchronized, so only one thread can access any method at a time.
Map<String, Integer> map = new Hashtable<>();
map.put("apple", 1);
map.put("banana", 2);
Integer value = map.get("apple");
✅ Thread-safe out-of-the-box
❌ Very inefficient under high concurrency (coarse-grained locking)
π‘ Avoid in modern applications; prefer ConcurrentHashMap
3. ⚡ ConcurrentHashMap
ConcurrentHashMap is designed for high-performance concurrent use. Thread-safe with atomic per-key operations.
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.merge("apple", 1, Integer::sum); // atomic update
Integer value = map.get("apple");
✅ Multiple threads can read/write safely without locking the entire map
✅ Atomic per-key operations like computeIfAbsent and merge
4. π HashMap vs Hashtable vs ConcurrentHashMap
| Feature | HashMap | Hashtable | ConcurrentHashMap |
|---|---|---|---|
| Thread-safe | ❌ No | ✅ Yes (coarse sync) | ✅ Yes (fine-grained / CAS) |
| Allows null keys/values | ✅ Yes | ❌ No | ❌ No |
| Performance under concurrency | ❌ Unsafe | ⚠ Slow (all methods synchronized) | ✅ High (reads lock-free, writes bucket-level) |
| Scalability | ❌ Single-threaded only | ⚠ Poor | ✅ Good |
| Use case | Single-threaded map | Legacy multi-threaded | Modern concurrent applications |
5. π ️ How ConcurrentHashMap Works
- Lock-free reads:
get()does not block, always sees most recent value - Fine-grained locking: Writes like
put()orremove()lock only the affected bucket - CAS operations: Internal compare-and-swap ensures safe updates without locking the entire map
- Treeification: Buckets with high collisions turn into balanced trees for O(log N) lookups
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("apple", 1);
map.computeIfPresent("apple", (k, v) -> v + 1); // atomic per key
✅ Efficient even with thousands of threads reading/updating simultaneously
6. π Best Practices
- Use
HashMapfor single-threaded applications only - Avoid
Hashtablein modern code; it’s legacy and slow - Use
ConcurrentHashMapwhen multiple threads need safe shared access - Prefer
computeIfAbsentormergefor atomic updates instead of manual synchronization - Iterators are weakly consistent — reflect some state of the map while allowing concurrent updates
7. π Example: Atomic Counter per Key
ConcurrentHashMap<String, AtomicInteger> counters = new ConcurrentHashMap<>();
Runnable incrementTask = () -> {
counters.computeIfAbsent("apple", k -> new AtomicInteger()).incrementAndGet();
};
Thread t1 = new Thread(incrementTask);
Thread t2 = new Thread(incrementTask);
t1.start(); t2.start();
t1.join(); t2.join();
System.out.println("Apple count: " + counters.get("apple").get());
✅ Safe increment per key without locking the entire map
Conclusion
Choosing the right map implementation is crucial for performance and correctness in concurrent Java applications. HashMap is fast but unsafe for multi-threading, Hashtable is thread-safe but outdated, and ConcurrentHashMap provides modern, high-performance concurrency with atomic per-key operations. Understanding its implementation helps you write thread-safe, scalable applications efficiently.
Labels: Java, Concurrency, HashMap, Hashtable, ConcurrentHashMap, Multithreading, Performance, Thread Safety
Comments
Post a Comment