SynchronizedMap vs ConcurrentHashMap in Java

1. Introduction

In Java, Map interface implementations are used to store data in key-value pairs for quick lookup and manipulation. Among them, SynchronizedMap and ConcurrentHashMap are two map options that provide thread-safe operations. SynchronizedMap is a wrapper around any map that provides basic thread safety, while ConcurrentHashMap is a map implementation that provides better scalability in concurrent applications.

2. Key Points

1. SynchronizedMap synchronizes each individual method, which can be a performance bottleneck in highly concurrent situations.

2. ConcurrentHashMap uses multiple locks on segments of the map, reducing the contention and improving scalability.

3. SynchronizedMap locks the entire map for reading and writing, which means only one thread can access the map at a time.

4. ConcurrentHashMap allows concurrent reads without locking, and a limited number of updates to proceed concurrently.

5. Iteration over a SynchronizedMap requires manual synchronization if a thread-safe iteration is needed, whereas iterators of ConcurrentHashMap are designed to be used by concurrent threads.

3. Differences: SynchronizedMap vs ConcurrentHashMap in Java

SynchronizedMap ConcurrentHashMap
A synchronized wrapper around a Map, obtained through Collections.synchronizedMap(Map). A concurrent collection class designed for high concurrency without full method-level synchronization.
Provides a basic thread-safety mechanism for maps through method-level synchronization of the wrapped map. Uses segment locking (a form of bucket-level locking) and other techniques to allow concurrent reads and updates to the map with minimal blocking.
Every operation on the SynchronizedMap requires obtaining the lock on the whole map, which can lead to significant contention and reduced performance under high concurrency. Allows multiple readers and a certain number of writers to access the map simultaneously, significantly increasing performance under high concurrency.
Iterators obtained from a SynchronizedMap are not thread-safe and must be manually synchronized on the map. Iterators obtained from a ConcurrentHashMap are weakly consistent and do not require additional synchronization.
Does not allow null keys or values, similar to ConcurrentHashMap. Does not permit null keys or values, ensuring non-null contracts of map operations.
This is suitable for scenarios where a map is accessed by multiple threads but not heavily updated concurrently or where locking the entire map is not a performance concern. Best suited for high-concurrency scenarios, especially when updates to the map are frequent, and performance is critical.

4. Example

// Import the necessary classes
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MapComparison {
    public static void main(String[] args) {
        // Step 1: Create a normal HashMap
        Map<String, Integer> hashMap = new HashMap<>();

        // Step 2: Wrap it into a SynchronizedMap
        Map<String, Integer> syncMap = Collections.synchronizedMap(hashMap);

        // Step 3: Create a ConcurrentHashMap
        ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();

        // Add elements
        syncMap.put("One", 1);
        concurrentMap.put("One", 1);

        // Step 4: Print the class names of the maps
        System.out.println("SynchronizedMap class: " + syncMap.getClass().getName());
        System.out.println("ConcurrentHashMap class: " + concurrentMap.getClass().getName());
    }
}

Output:

SynchronizedMap class: java.util.Collections$SynchronizedMap
ConcurrentHashMap class: java.util.concurrent.ConcurrentHashMap

Explanation:

1. A HashMap is created and then wrapped with Collections.synchronizedMap to provide basic thread-safe functionality.

2. A ConcurrentHashMap is created directly, which is designed to handle concurrent use.

3. Both maps are used to store a single key-value pair, demonstrating their similar usage patterns.

4. The output displays the class names, highlighting that a SynchronizedMap is a wrapped HashMap and ConcurrentHashMap is its own separate class with concurrency features built-in.

5. When to use?

- Use SynchronizedMap in legacy code or when you need to synchronize access to an existing map that is not heavily used by concurrent threads.

- Use ConcurrentHashMap when working with a high-concurrency application. You need a map that can handle multiple threads of reading and writing without major blocking.

Comments