How to Synchronize HashMap in Java

Java HashMap is not synchronized by default. If we add/remove key-value pairs from a HashMap in a concurrent application where multiple threads are adding and removing pairs, we may end up having inconsistent state of the map. Learn to synchronize hashmap and ConcurrentHashMap in Java.

1. Synchronize HashMap – ConcurrentHashMap

Our first choice should always be using the ConcurrentHashMap class if we wish to use a Map in concurrent environment. ConcurrentHashMap support concurrent access to it’s key-value pairs by design. We do not need to perform any additional code modifications to enable synchronization on the map.

Please note that iterator obtained from ConcurrentHashMap does not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time. It means each iterator we obtain from a ConcurrentHashMap is designed to be used by a single thread and should not be passed around.

If we do so then there is no guarantee that one thread will see the changes to the map that the other thread performs (without obtaining a new iterator from the map). The iterator is guaranteed to reflect the state of the map at the time of it’s creation.

Let’s take an example of working with ConcurrentHashMap.

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class HashMapExample 
{
    public static void main(String[] args) throws CloneNotSupportedException 
    {
        ConcurrentHashMap<Integer, String> concurrHashMap = new ConcurrentHashMap<>();
        
        //Put require no synchronization
        concurrHashMap.put(1, "A");
        concurrHashMap.put(2, "B");
        
        //Get require no synchronization
        concurrHashMap.get(1);
        
        Iterator<Integer> itr = concurrHashMap.keySet().iterator();
        
        //Using synchronized block is advisable
        synchronized (concurrHashMap) 
        {
            while(itr.hasNext()) {
                System.out.println(concurrHashMap.get(itr.next()));
            }
        }
    }
}

Program output.

A
B

2. Synchronize HashMap – Collections.synchronizedMap()

Synchronized HashMap also works very similar to ConcurrentHashMap, with few differences.

SynchronizedHashMap is allows only one thread to perform read/write operations at a time because all of its methods are declared synchronized. ConcurrentHashMap allows multiple threads to work independently on different segments in the map. This allows higher degree of concurrency in ConcurrentHashMap and thus improve performance of the application in whole.

Iterators from both classes should be used inside synchronized block but the iterator from SynchronizedHashMap is fail-fast. ConcurrentHashMap iterators are not fail-fast.

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

public class HashMapExample 
{
    public static void main(String[] args) throws CloneNotSupportedException 
    {
        Map<Integer, String> syncHashMap = Collections.synchronizedMap(new HashMap<>());
        
        //Put require no synchronization
        syncHashMap.put(1, "A");
        syncHashMap.put(2, "B");
        
        //Get require no synchronization
        syncHashMap.get(1);
        
        Iterator<Integer> itr = syncHashMap.keySet().iterator();
        
        //Using synchronized block is advisable
        synchronized (syncHashMap) 
        {
            while(itr.hasNext()) {
                System.out.println(syncHashMap.get(itr.next()));
            }
        }
    }
}

Program output.

A
B

3. Difference between Synchronized HashMap and ConcurrentHashMap

Let’s identify few differences between both version of maps so that we can decide which one to choose in which condition.

  1. Multiple threads can add/remove key-value pairs from ConcurrentHashMap, while only one thread is allowed to make change in case of SynchronizedHashMap. This results higher degree of concurrency in ConcurrentHashMap.
  2. No need to lock the map to read a value in ConcurrentHashMap. A retrieval operation will return the value inserted by the most recent completed insert operation. A lock is required for read operation too in SynchronizedHashMap.
  3. ConcurrentHashMap doesn’t throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it. The iterator reflects the state of the map at the time of it’s creation. SynchronizedHashMap returns Iterator, which fails-fast on concurrent modification.

Drop me your questions related to synchronizing a hashmap in Java.

Happy Learning !!

Read More :

A Guide to Java HashMap
HashMap Java Docs
ConcurrentHashMap Java Docs

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.