Java ConcurrentMap Interface
In Java, the ConcurrentMap
interface is a sub-interface of the Map
interface that provides thread-safe operations on the map. It was introduced in Java 5 as part of the java.util.concurrent
package, which provides a set of thread-safe utilities for concurrent programming.
The ConcurrentMap
interface provides additional methods to the basic Map
interface that allow for atomic, thread-safe operations. Some of the key methods include:
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
.putIfAbsent
andreplace
operations are atomic, which means that they are thread-safe and can be used in concurrent programs without any additional synchronization.
Here is an example of how to use ConcurrentMap
in a multi-threaded program:
import java.util.concurrent.*; public class ConcurrentMapExample { public static void main(String[] args) throws InterruptedException { ConcurrentMap<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 ConcurrentMap
. 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" is printed to the console.