C

Core Java tutorial for beginners

Clean • Professional

Synchronized HashMap in Java – Thread Safety, Examples & Usage

3 minute

Synchronized HashMap in Java

A Synchronized HashMap is simply a thread-safe version of HashMap, created using the Collections.synchronizedMap() wrapper method.

It ensures only one thread can access the map at a time, providing full synchronization (global lock).


What is a Synchronized HashMap?

A Synchronized HashMap is a thread-safe version of HashMap.

If multiple threads modify it simultaneously, it may cause:

  • Data inconsistency
  • Race conditions
  • ConcurrentModificationException
  • Even structure corruption (in older JVMs)

To make a HashMap thread-safe, Java provides:

Map<K, V> syncMap = Collections.synchronizedMap(new HashMap<>());

This wraps the HashMap inside a synchronized wrapper.

All operations (put(), get(), remove()) become synchronized internally.

Package

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

How Synchronized HashMap Works Internally

It uses a single lock for the entire map.

Simplified internal code:

public V put(K key, V value) {
    synchronized (mutex) {
        return m.put(key, value);
    }
}

Effects:

  • Thread-safe
  • Slower when multiple threads operate
  • Only one thread can access any map operation at a time

Creating a Synchronized HashMap

1. Using Collections.synchronizedMap()

Map<String, Integer> map =
        Collections.synchronizedMap(new HashMap<>());

2. Simple Example

Map<String, Integer> map =
        Collections.synchronizedMap(new HashMap<>());

map.put("A", 1);
map.put("B", 2);

System.out.println(map.get("A"));

Iterating a Synchronized HashMap (IMPORTANT)

Even though the map is synchronized, iteration IS NOT thread-safe.

You must use a synchronized block:

Map<String, Integer> map =
        Collections.synchronizedMap(new HashMap<>());

synchronized (map) {
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " = " + entry.getValue());
    }
}

Skipping the synchronized block may cause ConcurrentModificationException.


Complete Example

import java.util.*;

public class Main {
    public static void main(String[] args) {

        Map<String, Integer> map =
                Collections.synchronizedMap(new HashMap<>());

        map.put("A", 1);
        map.put("B", 2);

        synchronized (map) {
            for (String key : map.keySet()) {
                System.out.println(key + " : " + map.get(key));
            }
        }
    }
}

Drawbacks of SynchronizedHashMap

IssueExplanation
SlowEntire map is locked for every operation
No scalabilityNot good for high concurrency
Weak concurrencyIteration needs manual synchronization

Alternatives to Synchronized HashMap

OptionThread-safePerformanceNotes
Collections.synchronizedMapYesSlowUses single lock
HashtableYesSlowLegacy, synchronized methods
ConcurrentHashMapYesFastFine-grained locking, best choice

Difference: SynchronizedMap vs ConcurrentHashMap

FeatureSynchronizedMapConcurrentHashMap
Thread SafetyThread-safe using global lockThread-safe using fine-grained locking (Java 8+ uses CAS + bins)
Locking MechanismLocks the entire map for every operationLocks only portions (buckets/segments), allowing concurrent reads/writes
PerformanceSlow under heavy concurrencyHigh-performance, scalable under multiple threads
Null Keys / ValuesNot allowedNot allowed
IterationFail-fast (throws ConcurrentModificationException)Weakly consistent (does not throw exceptions, may reflect some updates)
Read OperationsRequire lock → slowerMostly lock-free → faster
Write OperationsSingle thread at a timeMultiple threads can update concurrently
Use CaseSimple thread safety for small mapsHigh-performance concurrent applications

Difference: SynchronizedMap vs Hashtable vs ConcurrentHashMap

FeatureHashtableSynchronizedMapConcurrentHashMap
Thread SafetyYes (fully synchronized)Yes (wrapper makes it synchronized)Yes (high-performance concurrency)
Synchronization TypeMethod-level lockingObject-level locking (on entire map)Fine-grained locking (bucket-level)
PerformanceSlowest (full map lock)Slow (full map lock)Fastest (no global lock)
Allows Null Key/ValueNo null key/valueNo null key/valueNo null key/value
Concurrency LevelVery lowVery lowVery high (multiple threads can update safely)
Iteration BehaviorFail-FastFail-FastWeakly Consistent (no exceptions)
Introduced InJava 1.0Java 1.2Java 1.5
Use CaseLegacy codeWrap a normal map for basic thread safetyHigh-performance concurrent applications
Underlying StructureHashTableAny Map (usually HashMap)Hash buckets (Java 8 uses CAS + tree bins)
Null Handling ReasonChecking null causes ambiguity in sync methodsFollows Hashtable rulesAvoid ambiguity in concurrent operations

When to Use Synchronized HashMap?

Use it when:

  • Few threads
  • Small data volume
  • Performance is not critical
  • You need simple, full synchronization

Avoid it when:

  • Many threads
  • High read/write operations
  • You need scalability

In such cases, always use ConcurrentHashMap.


Real-Life Use Cases

  • Small shared configuration maps
  • Simple utilities in multi-threaded environments
  • Legacy code needing thread-safety

Points to Remember

  • HashMap is not thread-safe
  • SynchronizedMap adds global locking
  • Must use manual synchronization during iteration
  • Slower for multi-threaded applications
  • ConcurrentHashMap is the recommended modern alternative

Article 0 of 0