πŸ—Ί️ 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

FeatureHashMapHashtableConcurrentHashMap
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 caseSingle-threaded mapLegacy multi-threadedModern concurrent applications

5. πŸ› ️ How ConcurrentHashMap Works

  • Lock-free reads: get() does not block, always sees most recent value
  • Fine-grained locking: Writes like put() or remove() 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 HashMap for single-threaded applications only
  • Avoid Hashtable in modern code; it’s legacy and slow
  • Use ConcurrentHashMap when multiple threads need safe shared access
  • Prefer computeIfAbsent or merge for 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

Popular posts from this blog

πŸ› ️ The Code Hut - Index

πŸ›‘️ Resilience Patterns in Distributed Systems

πŸ›‘️ Thread-Safe Programming in Java: Locks, Atomic Variables & LongAdder