How to create Synchronized HashMap in Java

 



To make a HashMap synchronized (i.e., thread-safe), you can use several approaches in Java. Here are the most common ones:

1. Using Collections.synchronizedMap

The Collections.synchronizedMap method provides a synchronized (thread-safe) Map backed by the specified HashMap. This method ensures that all accesses to the map are properly synchronized, making it thread-safe.

Here's an example:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SynchronizedHashMapExample {
public static void main(String[] args) {
// Create a HashMap
HashMap<String, Integer> hashMap = new HashMap<>();

// Create a synchronized (thread-safe) map backed by the HashMap
Map<String, Integer> synchronizedMap = Collections.synchronizedMap(hashMap);

// Now you can safely use synchronizedMap in a multithreaded environment
synchronizedMap.put("apple", 1);
synchronizedMap.put("banana", 2);

// When iterating over the synchronized map, you must synchronize on the map object
synchronized (synchronizedMap) {
for (Map.Entry<String, Integer> entry : synchronizedMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
}

2. Using ConcurrentHashMap

If you need a more scalable and concurrent alternative, you can use ConcurrentHashMap from the java.util.concurrent package. ConcurrentHashMap is designed for concurrent use and offers better performance in highly concurrent scenarios compared to a synchronized HashMap.

Here's an example:

import java.util.concurrent.ConcurrentHashMap;

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

// Now you can safely use concurrentMap in a multithreaded environment
concurrentMap.put("apple", 1);
concurrentMap.put("banana", 2);

// Iterating over ConcurrentHashMap does not require additional synchronization
for (Map.Entry<String, Integer> entry : concurrentMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}

3. Custom Synchronization

If you have special synchronization needs, you can manually synchronize the relevant code blocks using a synchronized block.

Here's an example:

import java.util.HashMap;
import java.util.Map;

public class CustomSynchronizedHashMapExample {
private final Map<String, Integer> hashMap = new HashMap<>();

public synchronized void put(String key, Integer value) {
hashMap.put(key, value);
}

public synchronized Integer get(String key) {
return hashMap.get(key);
}

public synchronized void remove(String key) {
hashMap.remove(key);
}

public static void main(String[] args) {
CustomSynchronizedHashMapExample customMap = new CustomSynchronizedHashMapExample();

// Safely use customMap in a multithreaded environment
customMap.put("apple", 1);
customMap.put("banana", 2);

System.out.println(customMap.get("apple"));
}
}

Summary

  • Collections.synchronizedMap: Simple way to synchronize a HashMap.
  • ConcurrentHashMap: Provides better performance and scalability for concurrent access.
  • Custom Synchronization: Gives more control over synchronization but requires careful implementation.

Choose the approach that best fits your needs based on the level of concurrency and performance requirements.

Comments