Unlocking the Power of ConcurrentHashMap in Java: Boosting Scalability and Performance in Java

ConcurrentHashMap in Java

  • In Java, the ConcurrentHashMap class is a part of the java.util.concurrent package and gives a thread-safe, high-performance usage of the Map interface.
  • Not at all like other map implementations, such as HashMap, which are not thread-safe, ConcurrentHashMap permits concurrent read and type in operations without locking the whole map, guaranteeing way better adaptability and execution in multi-threaded situations.
  • ConcurrentHashMap is planned for applications where numerous threads access and adjust a shared map concurrently.
  • It uses a method known as segmentation (or bucketization) to permit threads to concurrently access distinctive parts of the map without interferometer with each other.
  • Let’s jump into the details of this class, including its inside workings and utilization with examples.
 ConcurrentHashMap in Java
ConcurrentHashMap in Java

Key Highlights of ConcurrentHashMap in Java

1.Thread-Safety:
  • ConcurrentHashMap permits different threads to examined and compose concurrently without the risk of data corruption.
  • It accomplishes this by partitioning the map into sections and locking as it were the section that’s being altered.
2.Fine-Grained Locking:
  • Not at all like a single lock on the whole map (as in synchronized collections), ConcurrentHashMap uses a finer-grained locking mechanism.
  • Rather than locking the entire map, it locks as it were the segment or part of the map being accessed or altered.
3.No Locking on Reads:
  • One of the foremost critical advantages of ConcurrentHashMap is that it permits lock-free reads.
  • Numerous threads can read from the map at the same time without any execution hit, indeed whereas other threads are performing compose operations.
4.High Concurrency:
  • The execution is ideal for scenarios where numerous threads read and type in to the map at the same time.
  • It accomplishes this by inside dividing the information and locking as it were the partition being composed to.
5.Atomic Operations:
  • ConcurrentHashMap gives atomic operations like putIfAbsent(), remove(), and replace() that guarantee thread-safety for individual operations.

Internal Structure and Locking Mechanism

  • Inside, ConcurrentHashMap separates the map into numerous sections. Each section is basically a separate bucket, and each fragment can be locked freely.
  • This permits distinctive threads to alter distinctive fragments concurrently without blocking each other.
  • Furthermore, bucketization makes a difference reduce contention and increments throughput.
  • For example, in case there are numerous threads performing studied and type in operations on the map, one thread may well be adjusting a particular fragment, whereas other threads can still read or compose to other segments concurrently.

Key Methods in ConcurrentHashMap in Java

1.putIfAbsent(K key, V value):
  • Inserts a key-value pair as it were in case the key isn’t as of now show.
  • It is thread-safe, meaning that it avoids overwriting existing values during concurrent access.
2.remove(Object key, Object value):
  • Removes the entry for the desired key as it were in case it is as of now mapped to the desired value.
  • Typically an atomic operation, guaranteeing thread security when removing entries.
3.replace(K key, V oldValue, V newValue):
  • Replaces the value related with the desired key as it were in case the current value is equal to the anticipated value.
  • This makes a difference avoid overwriting with stale information during concurrent access.
4.computeIfAbsent(K key, Function <? super K, ? extends V> mappingFunction):
  • Computes and inserts a value in case the key isn’t already display within the map, utilizing the given mapping work.
  • This operation is atomic, guaranteeing that no other thread adjusts the map whereas the computation takes put.
5.forEach(BigConsumer<? super K,? super V> action):
  • Repeats over all key-value pairs within the map and applies the given activity to each pair.
  • The operation is thread-safe.

Example 1: Fundamental Usage of ConcurrentHashMap in Java

Let’s see at a straightforward example where numerous threads perform put and get operations on a ConcurrentHashMap:

import java.util.concurrent.*;

public class ConcurrentHashMapExample {
public static void main(String[] args) {
// Create a ConcurrentHashMap
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// Create threads that update the map concurrently
Runnable task1 = () -> {
for (int i = 0; i < 10; i++) {
map.putIfAbsent("Key" + i, i); // Only inserts if the key is not present
}
};

Runnable task2 = () -> {
for (int i = 5; i < 15; i++) {
map.putIfAbsent("Key" + i, i); // Only inserts if the key is not present
}
};

// Start the threads
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
thread1.start();
thread2.start();

// Wait for threads to finish
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

// Print the map
System.out.println("Map: " + map);
}
}

Clarification:
  • We make a ConcurrentHashMap and after that produce two threads. Both threads attempt to insert key-value pairs into the map.
  • The putIfAbsent() method guarantees that a key is only inserted in case it isn’t as of now show.
  • Indeed in spite of the fact that both threads may attempt to insert the same key, as it were one thread can insert it, and the other thread will see the key as as of now existing.
  • The result of the program appears the ultimate state of the map after both threads complete their execution.
  • You’ll take note that each key-value pair shows up as it were once, indeed in spite of the fact that both threads attempted to add overlapping keys.

Example 2: Using Atomic Operations

  • In this example, we illustrate the use of atomic methods like replace() and putIfAbsent() to upgrade values atomically:

import java.util.concurrent.*;

public class AtomicOperationsExample {
public static void main(String[] args) {
// Create a ConcurrentHashMap
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// Insert an entry if absent
map.putIfAbsent("apple", 5);

// Replace the value if the current value matches the expected value
map.replace("apple", 5, 10); // apple's value will change to 10

// Try to remove an entry only if the current value matches the expected value
boolean removed = map.remove("apple", 10); // Returns true if the entry was removed

// Output the map and removal status
System.out.println("Map after operations: " + map);
System.out.println("Was the 'apple' entry removed? " + removed);
}
}

Clarification:
  • We use putIfAbsent() to insert a key-value pair as it were in case the key “apple” isn’t as of now show.
  • We at that point utilize replace() to atomically replace the value related with the key “apple”, but as it were in case the current value matches the anticipated value (5 in this case).
  • We demonstrate the atomic remove() method, which removes the entry as it were in case its value is 10.

Leave a Comment