Java ConcurrentHashMap
ConcurrentHashMap
is a thread-safe implementation of the Map
interface in Java. It provides all the functionality of a HashMap
along with additional concurrency control mechanisms to support safe access by multiple threads.
ConcurrentHashMap
is part of the java.util.concurrent
package and was introduced in Java 5. It is designed to provide better concurrency than the synchronized collections like Hashtable
and Collections.synchronizedMap()
, which use a single lock to synchronize all the operations on the collection.
The main features of ConcurrentHashMap
are:
Thread-safe:
ConcurrentHashMap
is designed to support concurrent access from multiple threads without any additional locking mechanism.Higher concurrency: Unlike synchronized collections,
ConcurrentHashMap
divides the map into several segments and provides concurrency control on each segment independently, which allows multiple threads to access different segments of the map concurrently.No blocking:
ConcurrentHashMap
does not block any threads while accessing the map. Multiple threads can access the map concurrently, and if one thread is blocked on a particular segment, other threads can still access the other segments of the map.
Some of the key methods of ConcurrentHashMap
are:
putIfAbsent(key, value)
- adds the key-value pair to the map if the key is not already present, and returnsnull
. If the key is already present, the current value is returned.remove(key, value)
- removes the key-value pair from the map if the key is currently mapped to the given value, and returnstrue
. If the key is not currently mapped to the given value, the method returnsfalse
.replace(key, oldValue, newValue)
- replaces the value of the key with the new value if the current value is equal to the old value, and returnstrue
. If the current value is not equal to the old value, the method returnsfalse
.
Here's an example of using ConcurrentHashMap
in a multi-threaded program:
import java.util.concurrent.*; public class ConcurrentHashMapExample { public static void main(String[] args) throws InterruptedException { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); // Creating two threads to increment the value associated with the key "counter" Thread t1 = new Thread(() -> { for (int i = 0; i < 10000; i++) { map.putIfAbsent("counter", 0); map.computeIfPresent("counter", (key, val) -> val + 1); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 10000; i++) { map.putIfAbsent("counter", 0); map.computeIfPresent("counter", (key, val) -> val + 1); } }); // Starting the threads t1.start(); t2.start(); // Waiting for the threads to finish t1.join(); t2.join(); // Displaying the value associated with the key "counter" System.out.println("Counter value: " + map.get("counter")); } }
Output:
Counter value: 20000
In this example, two threads are created to increment the value associated with the key "counter" in the ConcurrentHashMap
. The putIfAbsent
method is used to add the key "counter" with an initial value of 0 if it is not already present. The computeIfPresent
method is used to increment the value of the key "counter" atomically. The join()
method is used to wait for the threads to finish, and the final value of the key "counter