Java HashMap vs ConcurrentHashMap

In this post, we will learn the difference between HashMap and ConcurrentHashMap in Java. This is a frequently asked question in Java interviews for beginners. Let's dive into it.

Difference between HashMap and ConcurrentHashMap in Java

Example

Let's create an example to illustrate the difference between HashMap and ConcurrentHashMap in Java.

HashMap is a non-thread-safe implementation of a map, where elements can be added, updated, and removed. However, it is not suitable for concurrent access from multiple threads without proper synchronization, as it may lead to unexpected behavior or even data corruption. 

ConcurrentHashMap, on the other hand, is a thread-safe implementation of a map, designed to support high concurrency. It allows multiple threads to read and write concurrently without external synchronization. It achieves this by dividing the map into segments and applying separate locks to each segment. 

Let's see an example:

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

public class HashMapVsConcurrentHashMapExample {
    public static void main(String[] args) {
        // HashMap example (non-thread-safe)
        HashMap<Integer, String> hashMap = new HashMap<>();

        Runnable hashMapRunnable = () -> {
            for (int i = 0; i < 5; i++) {
                hashMap.put(i, "Value " + i);
                String value = hashMap.get(i);
                System.out.println("HashMap - Key: " + i + ", Value: " + value);
            }
        };

        // Create multiple threads using the same Runnable (not thread-safe)
        Thread hashMapThread1 = new Thread(hashMapRunnable);
        Thread hashMapThread2 = new Thread(hashMapRunnable);

        // Start the threads
        hashMapThread1.start();
        hashMapThread2.start();

        // ConcurrentHashMap example (thread-safe)
        ConcurrentHashMap<Integer, String> concurrentHashMap = new ConcurrentHashMap<>();

        Runnable concurrentHashMapRunnable = () -> {
            for (int i = 0; i < 5; i++) {
                concurrentHashMap.put(i, "Value " + i);
                String value = concurrentHashMap.get(i);
                System.out.println("ConcurrentHashMap - Key: " + i + ", Value: " + value);
            }
        };

        // Create multiple threads using the same Runnable (thread-safe)
        Thread concurrentHashMapThread1 = new Thread(concurrentHashMapRunnable);
        Thread concurrentHashMapThread2 = new Thread(concurrentHashMapRunnable);

        // Start the threads
        concurrentHashMapThread1.start();
        concurrentHashMapThread2.start();
    }
}

Output:

HashMap - Key: 0, Value: Value 0
HashMap - Key: 0, Value: Value 0
HashMap - Key: 1, Value: Value 1
HashMap - Key: 1, Value: Value 1
HashMap - Key: 2, Value: Value 2
HashMap - Key: 2, Value: Value 2
HashMap - Key: 3, Value: Value 3
HashMap - Key: 3, Value: Value 3
HashMap - Key: 4, Value: Value 4
HashMap - Key: 4, Value: Value 4
ConcurrentHashMap - Key: 0, Value: Value 0
ConcurrentHashMap - Key: 0, Value: Value 0
ConcurrentHashMap - Key: 1, Value: Value 1
ConcurrentHashMap - Key: 1, Value: Value 1
ConcurrentHashMap - Key: 2, Value: Value 2
ConcurrentHashMap - Key: 2, Value: Value 2
ConcurrentHashMap - Key: 3, Value: Value 3
ConcurrentHashMap - Key: 3, Value: Value 3
ConcurrentHashMap - Key: 4, Value: Value 4
ConcurrentHashMap - Key: 4, Value: Value 4

Explanation: 

In the example, we first demonstrate the behavior of HashMap, which is not thread-safe. We create two threads that execute the same hashMapRunnable, which adds elements to the HashMap. The threads may interfere with each other and cause unexpected behavior, leading to incorrect or missing output. This demonstrates that HashMap is not suitable for concurrent access from multiple threads without proper synchronization. 

Next, we demonstrate the behavior of ConcurrentHashMap, which is thread-safe. We create two threads that execute the same concurrentHashMapRunnable, which adds elements to the ConcurrentHashMap.

Since ConcurrentHashMap is designed for concurrent access, it properly handles multiple threads accessing it simultaneously, and we get consistent and correct output. 

Note: The actual output may vary in different runs due to the concurrent nature of the threads. The key takeaway is that ConcurrentHashMap is suitable for concurrent access, while HashMap is not.


Comments