Java ConcurrentHashMap

ht‮ww//:spt‬w.theitroad.com

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 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.

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