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 returns null. 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 returns true. If the key is not currently mapped to the given value, the method returns false.

  • 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 returns true. If the current value is not equal to the old value, the method returns false.

  • putIfAbsent and replace 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:

ref‮‬er to:theitroad.com
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.