In Java, ConcurrentHashMap and HashMap are two different implementations of the Map interface that are used to store key-value pairs. However, they differ in their thread-safety and performance characteristics.
HashMap is not thread-safe and can result in ConcurrentModificationException if accessed by multiple threads concurrently without proper synchronization. On the other hand, ConcurrentHashMap is designed to be thread-safe and can be safely accessed by multiple threads without the need for external synchronization.
Here are some key differences between ConcurrentHashMap and HashMap in Java:
Thread-safety: As mentioned, HashMap is not thread-safe whereas ConcurrentHashMap is thread-safe. This means that ConcurrentHashMap can be safely accessed by multiple threads concurrently without external synchronization. However, HashMap should be synchronized externally if it is accessed by multiple threads concurrently.
Performance: In terms of performance, ConcurrentHashMap is optimized for concurrent access and can perform better than HashMap in concurrent scenarios. HashMap, on the other hand, can perform better than ConcurrentHashMap in single-threaded scenarios.
Iteration: When iterating over a ConcurrentHashMap, the iterator returned by the entrySet() method is weakly consistent, which means that it can return the elements as they existed at some point in time, but it doesn’t guarantee that the iterator will reflect any changes made to the map after it was created. In contrast, iterating over a HashMap is fail-fast, which means that if the map is modified during iteration, it will throw a ConcurrentModificationException.
Null values and keys: Both HashMap and ConcurrentHashMap allow null values to be stored. However, ConcurrentHashMap does not allow null keys, whereas HashMap does.
Here is an example code snippet that demonstrates the difference between HashMap and ConcurrentHashMap in Java:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MapExample {
public static void main(String[] args) {
// Example of a HashMap
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("One", 1);
hashMap.put("Two", 2);
hashMap.put("Three", 3);
// Accessing a HashMap from multiple threads without
// synchronization can cause ConcurrentModificationException
Runnable runnable = () -> {
for (String key : hashMap.keySet()) {
System.out.println(key + " : " + hashMap.get(key));
}
};
new Thread(runnable).start();
new Thread(runnable).start();
// Example of a ConcurrentHashMap
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("One", 1);
concurrentHashMap.put("Two", 2);
concurrentHashMap.put("Three", 3);
// Concurrent access to a ConcurrentHashMap is thread-safe
Runnable runnable2 = () -> {
for (String key : concurrentHashMap.keySet()) {
System.out.println(key + " : " + concurrentHashMap.get(key));
}
};
new Thread(runnable2).start();
new Thread(runnable2).start();
}
}
In the example above, we create a HashMap and a ConcurrentHashMap and add some key-value pairs to them. We then create two threads that attempt to iterate over the map and print its contents. In the case of the HashMap, this results in a ConcurrentModificationException since the map is not thread-safe and is being accessed by multiple threads concurrently without synchronization. In contrast, the ConcurrentHashMap can be safely