Skip to main content

How to synchronize HashMap in Java

How to synchronize HashMap in Java?

In this article, we are going to learn how we can synchronize HashMap in Java. As we know, HashMap is not synchronized in java i.e., it is not thread-safe. So we must know how to make HashMap synchronized to use it in the multi-threaded environment.

Why HashMap is not Synchronized?

First, we should know "Why HashMap is not Synchronized?" before knowing how to make that synchronized. HashMap is used in almost all real-world scenarios and if HashMap is synchronized then it would be much slower as compared to the current implementation. Because to make any class synchronized, it needs performance overhead.
Therefore, the developers of HashMap made it as non-synchronized to work faster and provide other ways to synchronize HashMap.

There are two ways to synchronize HashMap in Java:
  • Using Collections.synchronizedMap() method
  • Using ConcurrentHashMap class

Content of the Article


How to synchronize HashMap in Java - Using Collections.synchronizedMap() method

The synchronizedMap() is a static method of java.util.Collections class. This method takes an argument of Map<k, V> type and returns an instance of Map<k, V> type but this returned Map is synchronized.
Syntax
HashMap<K, V> hashMap = new HashMap<>();
Map<K, V> synchronizedMap = Collections.synchronizedMap(hashMap);
This returned Map is synchronized i.e., it is a thread-safe variant of the HashMap. All the method of this HashMap is synchronized to each other i.e, At any time, only one thread can operate any operation onto the HashMap.
Also, important to note that if we iterate this synchronized HashMap using iterator then we must iterate within the synchronized block or synchronized method because the iterators provided by the HashMap is not synchronized.
Read this article to learn: Different ways to iterate HashMap in Java

Java Synchronized HashMap Example 1: iterate synchronized HashMap using synchronized block.

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

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, String> cities = new HashMap<>();
        cities.put("Mumbai", "India");
        cities.put("Delhi", "India");
        cities.put("New York", "USA");
        cities.put("London", "England");
        cities.put("Beijing", "China");

        // Synchronized HashMap
        Map<String, String> synchronizedMap 
                  = Collections.synchronizedMap(cities);

        // Starting printingThread-1
        printingThread("Thread 1", synchronizedMap);

        // Starting printingThread-1
        printingThread("Thread 2", synchronizedMap);
    }

    public static void printingThread(String threadName, Map<String, String> synchronizedMap) {
        Runnable runnable = () -> {
            synchronized (synchronizedMap) {
                System.out.println(
                    "-------Synchronized Block of " + Thread.currentThread().getName() + " started----------");
                Iterator<Entry<String, String>> iterator = synchronizedMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<String, String> entry = iterator.next();
                    System.out.println(Thread.currentThread().getName() 
                    + " = [ " + entry.getKey() + " : " + entry.getValue() + " ]");
                }
                System.out.println(
                    "-------Synchronized Block of " + Thread.currentThread().getName() + " ended------------");
            }
        };
        Thread thread = new Thread(runnable, threadName);
        thread.start();
    }
}
Output
-------Synchronized Block of Thread 1 started----------
Thread 1 = [ Beijing : China ]
Thread 1 = [ Delhi : India ]
Thread 1 = [ New York : USA ]
Thread 1 = [ London : England ]
Thread 1 = [ Mumbai : India ]
-------Synchronized Block of Thread 1 ended------------
-------Synchronized Block of Thread 2 started----------
Thread 2 = [ Beijing : China ]
Thread 2 = [ Delhi : India ]
Thread 2 = [ New York : USA ]
Thread 2 = [ London : England ]
Thread 2 = [ Mumbai : India ]
-------Synchronized Block of Thread 2 ended------------
As you can see, first the synchronized block of Thread-1 has been started, iterate over the synchronized HashMap and ended. After that, the synchronized block of Thread-2 was started. This happened due to the presence of synchronized block in the thread if we do not use synchronized block then both the thread iterate HashMap parallelly and during that, if any other thread performs any modification onto the HashMap, the ConcurrentModificationException would be raised.

After The Java 8

Java 8 introduced the forEach() method for iterate and as we learn above, all the methods of the synchronized HashMap are synchronized with each other. Therefore, we can use the forEach() method to iterate the synchronized HashMap without using synchronized block and also we don't need to worry about the other thread working on the same HashMap as the forEach() method also synchronized with other methods.
Let's understand this with an example:

Java Synchronized HashMap Example 2: iterate synchronized HashMap using forEach() method.

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

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, String> cities = new HashMap<>();
        cities.put("Mumbai", "India");
        cities.put("Delhi", "India");
        cities.put("New York", "USA");
        cities.put("London", "England");
        cities.put("Beijing", "China");

        // Synchronized HashMap
        Map<String, String> synchronizedMap 
                  = Collections.synchronizedMap(cities);

        // Starting printingThread-1
        printingThread("Thread 1", synchronizedMap);

        // Starting printingThread-1
        printingThread("Thread 2", synchronizedMap);
    }

    public static void printingThread(String threadName, Map<String, String> synchronizedMap) {
        Runnable runnable = () -> {
            synchronizedMap.entrySet().forEach(entry -> {
                System.out.println(Thread.currentThread().getName() 
                    + " = [ " + entry.getKey() + " : " + entry.getValue() + " ]");
            }); 
        };
        Thread thread = new Thread(runnable, threadName);
        thread.start();
    }
}
Output
Thread 1 = [ Beijing : China ]
Thread 1 = [ Delhi : India ]
Thread 1 = [ New York : USA ]
Thread 1 = [ London : England ]
Thread 1 = [ Mumbai : India ]
Thread 2 = [ Beijing : China ]
Thread 2 = [ Delhi : India ]
Thread 2 = [ New York : USA ]
Thread 2 = [ London : England ]
Thread 2 = [ Mumbai : India ]

How to synchronize HashMap in Java - Using ConcurrentHashMap class?

We can also use ConcurrentHashMap class to synchronize HashMap in the multithreaded environment. The ConcurrentHashMap class is defined in java.util.concurrent package. The ConcurrentHashMap is implemented upon the HashTable and it works on the principle of Segment locking or Bucket locking.
"According to Bucket locking, any number of threads can perform read or retrieval operations onto the ConcurrentHashMap at the same time but when any thread wants to perform any update operation, first it needs to get the lock over the bucket and can perform any update operations only on the locked bucket."

Java Synchronized HashMap Example 3: create and iterate ConcurrentHashMap.

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, String> cities = new HashMap<>();
        cities.put("Mumbai", "India");
        cities.put("Delhi", "India");
        cities.put("New York", "USA");
        cities.put("London", "England");
        cities.put("Beijing", "China");

        // Synchronized HashMap
        ConcurrentHashMap<String, String> concurrentHashMap 
                  = new ConcurrentHashMap<>(cities);

        // Starting printingThread-1
        printingThread("Thread 1", concurrentHashMap);

        // Starting printingThread-1
        printingThread("Thread 2", concurrentHashMap);
    }

    public static void printingThread(String threadName, ConcurrentHashMap<String, String> concurrentHashMap) {
        Runnable runnable = () -> {
            concurrentHashMap.entrySet().forEach(entry -> {
                // Add delay of 100 milliseconds. Meanwhile, CPU can switch between threads.
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {}

                System.out.println(Thread.currentThread().getName() 
                    + " = [ " + entry.getKey() + " : " + entry.getValue() + " ]");
            }); 
        };
        Thread thread = new Thread(runnable, threadName);
        thread.start();
    }
}
Output
Thread 2 = [ Beijing : China ]
Thread 1 = [ Beijing : China ]
Thread 2 = [ Delhi : India ]
Thread 1 = [ Delhi : India ]
Thread 2 = [ New York : USA ]
Thread 1 = [ New York : USA ]
Thread 1 = [ London : England ]
Thread 2 = [ London : England ]
Thread 1 = [ Mumbai : India ]
Thread 2 = [ Mumbai : India ]
As we can see from the output, both threads are iterating ConcurrentHashMap parallelly. Also, if any other thread made some modifications to the same ConcurrentHashMap, it will not raise any exception because of the bucket locking.

Related Article


Comments

Popular posts from this blog

How HashMap works internally in java

How Hashmap works Internally in Java In this article, we are going to see how HashMap internally works in java. Also, we will have a look at what Java 8 made changes on the internal working of Hashmap to make it faster. What is Hashmap and Hashing in java? How Hashmap works Internally in Java is majorly dependent upon the Hashing Principle. So, Before going to learn how HashMap works internally in java, lets first understand what is HashMap and hashing. HashMap : A HashMap is a map used to store mappings of key-value pairs. Also, it works on the Principle of Hashing. To know more about the HashMap, visit this article: HashMap in Java Hashing Principle : Simply, Hashing is a method used to produce an integer value from an object and this integer value known as the hash value. In HashMap, the key object is used for Hashing.
Internal Struture of the HashMap in java For internal working of HashMap, HashMap maintains an array of bucket, each bucket is a linked-list and linked list is a li…

HashMap in Java

HashMap in Java In this article, we are going to learn about the most important class of Java known as HashMap. HashMap in java is the most used map interface and it is used in our regular or day-to-day programming practices.
What is HashMap in java? Lets first start with basic definition of HashMap,
HashMap is a map which store key-value pair, where each key is mapped with a value.
HashMap defined in java.util package and implements map interface which provides functionalities to perform basic operation like store, retrieve, size of the map etc. It is a part of Java Collection Framework. Time complexity of HashMap in Java? : Time complexity to store and retrieve data from the HashMap is O(1) in the Best Case. But it can be O(n) in the worst case and after the changes made in Java 8 the worst case time complexity can be O(log n) atmost. Internal working of HashMap in java HashMap maintains an array of the buckets, where each bucket is a linked-list and the linked list is a list of…

ArrayList in Java

ArrayList in Java In this article, we are going to discuss ArrayList in Java. ArrayList is a class from the Java Collection Framework and widely in our programs. We use ArrayList as a substitute for the array. So, it is important to know ArrayList in detail. We are going to see what is ArrayList in Java, how we can create the instance of ArrayList and the methods provided by the ArrayList in Java.

If you already familiar to ArrayList, you may learn common programs related to ArrayList.
Table of ContentsWhat is ArrayList in Java?Hierarchy of the ArrayList in java?How to create objects of ArrayList in Java?How to create an ArrayList of Custom Objects?How to iterate ArrayList in Java?How to get the elements by index from ArrayList in Java?How to check whether an elements is stored in the ArrayList in Java?How to remove elements from the ArrayList in Java?Few more methods of ArrayList in Java?
What is ArrayList in Java? ArrayList in Java is a List in which we can store and retrieve elemen…