Create Thread-safe HashMap Without Using Collections.synchronizedMap in Java
Last Updated :
31 Jan, 2024
The HashMap class in Java is a commonly used data structure for storing key-value pairs. While HashMap provides fast and efficient operations, it is not inherently thread-safe. When working in a multi-threaded environment, it's crucial to ensure that data structures are accessed and modified in a way that prevents race conditions and maintains consistency.
In this article, we will learn How to create a thread-safe HashMap without using Collections.synchronizedMap in Java.
Thread-Safe HashMap Without Using Collections.synchronizedMap in Java
One commonly used approach to achieving thread safety with a HashMap is to use the Collections.synchronizedMap method. However, there's an alternative method to create a thread-safe HashMap without relying on this utility.
The Challenge of Thread Safety: In a multi-threaded environment, simultaneous access to a non-thread-safe HashMap can lead to data corruption and unpredictable behavior. To address this, developers often synchronize access to the HashMap using techniques such as Collections.synchronizedMap or manual synchronization with synchronized blocks.
1. Using ConcurrentHashMap - An Alternative
An alternative to explicit synchronization is to use the ConcurrentHashMap class, introduced in Java 5. ConcurrentHashMap is specifically designed for concurrent access and provides better performance in comparison to synchronized maps.
Here's an example of how you can create and use a thread-safe HashMap using ConcurrentHashMap:
Java
// Java program demonstrating the use of
// ConcurrentHashMap for thread-safe operations
import java.util.concurrent.ConcurrentHashMap;
// Class definition
public class ThreadSafeHashMapExample {
// Main method
public static void main(String[] args)
{
// Creating a thread-safe HashMap
// without using Collections.synchronizedMap
ConcurrentHashMap<String, Integer> threadSafeMap = new ConcurrentHashMap<>();
// Adding key-value pairs to the ConcurrentHashMap
threadSafeMap.put("One", 1);
threadSafeMap.put("Two", 2);
threadSafeMap.put("Three", 3);
// Accessing and printing values using forEach and a
// lambda expression
threadSafeMap.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
Output:
One: 1
Two: 2
Three: 3
In this example, the ConcurrentHashMap is used instead of a regular HashMap. The operations on this map are inherently thread-safe, eliminating the need for external synchronization.
2. Implementing Custom Thread-Safe HashMap
If you want to create a thread-safe HashMap without using ConcurrentHashMap, you can implement your own custom solution. One approach is to use locks to synchronize critical sections of code:
Java
// Java program demonstrating a custom
// thread-safe HashMap using explicit locks
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// CustomThreadSafeHashMap with generic
// key (K) and value (V) types
public class CustomThreadSafeHashMap<K, V> {
// Private instance variables
private final Map<K, V> map = new HashMap<>();
private final Lock lock = new ReentrantLock();
// Method to add a key-value pair
// to the map in a thread-safe manner
public void put(K key, V value) {
// Acquiring the lock
lock.lock();
try {
// Performing the put operation on the map
map.put(key, value);
} finally {
// Releasing the lock in a finally block
// to ensure it happens even if an exception occurs
lock.unlock();
}
}
// Method to retrieve a value associated
// with a key in a thread-safe manner
public V get(K key) {
// Acquiring the lock
lock.lock();
try {
// Performing the get operation on the map
return map.get(key);
} finally {
// Releasing the lock in a finally block
// to ensure it happens even if an exception occurs
lock.unlock();
}
}
// Main method for testing the CustomThreadSafeHashMap
public static void main(String[] args) {
// Creating an instance of CustomThreadSafeHashMap
// with String keys and Integer values
CustomThreadSafeHashMap<String, Integer> customThreadSafeMap = new CustomThreadSafeHashMap<>();
// Adding key-value pairs to the custom thread-safe map
customThreadSafeMap.put("One", 1);
customThreadSafeMap.put("Two", 2);
customThreadSafeMap.put("Three", 3);
// Accessing and printing values associated with specific keys
System.out.println("Value for key 'One': " + customThreadSafeMap.get("One"));
System.out.println("Value for key 'Two': " + customThreadSafeMap.get("Two"));
System.out.println("Value for key 'Three': " + customThreadSafeMap.get("Three"));
}
}
Output:
Value for key 'One': 1
Value for key 'Two': 2
Value for key 'Three': 3
In this example, a ReentrantLock is used to synchronize access to the HashMap. Each critical section of code is enclosed within lock and unlock calls, ensuring that only one thread can access the map at a time.
Similar Reads
How to Create a Synchronized HashTable in Java?
In Java, a synchronized HashTable is achieved by wrapping a regular HashTable with the Collection.synchronizedMap( ) method. This wrapper ensures that each method of the Map interface is synchronized, making the HashTable thread-safe. Syntax:Map<KeyType, ValueType> synchronizedHashTable = Coll
3 min read
How to Convert a HashTable to Other Collections Types in Java?
In Java, a Hashtable is a data structure that stores the data in the form of key and value pairs. And each key is mapped to a specific value. It implements the Map interface. HashTable provides a simple way to access the data using the unique keys. In this article, we will learn how to convert a Has
3 min read
Getting Synchronized Map from Java HashMap
HashMap is a non synchronized collection class. If we want to perform thread-safe operations on it then we must have to synchronize it explicitly. In order to synchronize it explicitly the synchronizedMap() method of java.util.Collections class is used to return a synchronized (thread-safe) map back
2 min read
How does HashMap handle resizing when it reaches its capacity in Java?
The capacity of a HashMap simply doubles when it reaches a certain threshold. The threshold depends on the initial capacity and the load factor of the HashMap. Consider Capacity as the number of spaces, a HashMap currently has to store elements and Load factor is a measure of how full the map is all
3 min read
Java Program to Read Elements using Enumeration in Hashtable
The enumeration in java is one of the predefined interfaces, whose object is used for retrieving the data from collections framework variable(like Stack, Vector, HashTable, etc.) in a forward direction only and not in the backward direction. HashTable is a class The hash table class implements a Map
3 min read
Getting Synchronized Map from Java TreeMap
TreeMap is a part of the Java Collections framework. Java TreeMap contains values based on the key. It implements the NavigableMap interface and extends AbstractMap class. It provides an efficient means of storing key-value pairs in sorted order. Java TreeMap contains only unique elements. It cannot
2 min read
Creating HashMap from Other Maps in Java
Map interface present in java.util package represents a mapping between a key and a value. The Map interface is not a subtype of the Collection interface. Therefore, it behaves a bit differently from the rest of the collection types. A map contains unique keys. There are three main types of maps in
3 min read
How to Handle Concurrent Access and Modification of a TreeMap Using Concurrent Collections in Java?
To solve data corruption in a multithreaded context, and thread safety, Java offers concurrent collections in the java.util.concurrent package. In this article, we will learn the use of concurrent collections to manage simultaneous access and change of a TreeMap. Concurrent Collections: Java concurr
2 min read
Load Factor in HashMap in Java with Examples
HashMap is a class that implements the Map interface of Java Collections Framework. The most important feature of a HashMap is that it has a constant time performance for retrieval and insertion. The two factors that dictate the performance of a HashMap are: Initial CapacityLoad Factor Before we exp
5 min read
Converting ArrayList to HashMap in Java 8 using a Lambda Expression
A lambda expression is one or more line of code which works like function or method. It takes a parameter and returns the value. Lambda expression can be used to convert ArrayList to HashMap. Syntax: (parms1, parms2) -> expressionExamples: Input : List : [1="1", 2="2", 3="3"] Output: Map : {1=1,
2 min read