Introduction
Java provides various collection classes, but when dealing with concurrency, standard HashMap
can lead to issues like race conditions and inconsistent data. To solve this, Java introduced ConcurrentHashMap
in the java.util.concurrent
package.
What is ConcurrentHashMap?
ConcurrentHashMap
is a thread-safe implementation of Map
that allows multiple threads to read and write efficiently.
- Supports high-performance concurrent access.
- Uses segment-based locking for efficient performance.
- Does not lock the entire map for reads.
- Faster than
Collections.synchronizedMap()
.
How Does ConcurrentHashMap Work?
Internally, ConcurrentHashMap
in Java uses a mechanism called lock striping where the map is divided into multiple segments (buckets). Only the required segment is locked instead of the whole map.
Key Features:
- Improved performance using bucket-level synchronization.
- Allows multiple threads to access different parts of the map simultaneously.
- Locking is applied at the segment level, reducing contention.
Example 1: Basic Usage of ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapExample { public static void main(String[] args) { ConcurrentHashMapmap = new ConcurrentHashMap<>(); // Adding elements map.put(1, "Java"); map.put(2, "Python"); map.put(3, "C++"); // Retrieving values System.out.println("Value at key 1: " + map.get(1)); // Iterating over keys map.forEach((key, value) -> System.out.println(key + " -> " + value)); } }
Example 2: Concurrent Modification
import java.util.concurrent.*; public class ConcurrentModificationExample { public static void main(String[] args) { ConcurrentHashMapmap = new ConcurrentHashMap<>(); map.put("A", 1); map.put("B", 2); map.put("C", 3); // Running threads to modify the map concurrently ExecutorService executor = Executors.newFixedThreadPool(2); Runnable task1 = () -> { map.put("D", 4); System.out.println("Thread 1 added D"); }; Runnable task2 = () -> { map.put("E", 5); System.out.println("Thread 2 added E"); }; executor.execute(task1); executor.execute(task2); executor.shutdown(); while (!executor.isTerminated()) {} System.out.println("Final Map: " + map); } }
ConcurrentHashMap vs HashMap vs SynchronizedMap
Feature | HashMap | ConcurrentHashMap | SynchronizedMap |
---|---|---|---|
Thread Safety | No | Yes | Yes |
Performance | Fast (single-threaded) | High performance (multi-threaded) | Slower |
Locking Mechanism | None | Bucket-level locking | Whole map locked |
Best Practices for Using ConcurrentHashMap
- Use when multiple threads need to access and modify a shared map.
- Avoid using
size()
in multi-threaded environments, as it may not be accurate. - For atomic operations, use
computeIfAbsent()
andcompute()
.
Conclusion
In Java, ConcurrentHashMap
is a powerful alternative to HashMap
when working in a multi-threaded environment. It provides better performance than Collections.synchronizedMap()
by reducing lock contention.