Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConcurrentHashMap vs Synchronized HashMap

Tags:

java

core

What is the difference between using the wrapper class, SynchronizedMap, on a HashMap and ConcurrentHashMap?

Is it just being able to modify the HashMap while iterating it (ConcurrentHashMap)?

like image 967
hello_world_infinity Avatar asked Aug 18 '09 04:08

hello_world_infinity


People also ask

What is the difference between ConcurrentHashMap and synchronized HashMap?

SynchronizedMap acquires lock on the entire Map instance , while ConcurrentHashMap divides the Map instance into multiple segments and locking is done on those.

Is HashMap faster than ConcurrentHashMap?

The summary If you choose a single thread access use HashMap , it is simply faster. For add method it is even as much as 3x more efficient. Only get is faster on ConcurrentHashMap , but not much.

Should ConcurrentHashMap be synchronized?

You should use ConcurrentHashMap when you need very high concurrency in your project. It is thread safe without synchronizing the whole map . Reads can happen very fast while write is done with a lock. There is no locking at the object level.

Which is better ConcurrentHashMap or HashTable?

ConcurrentHashMap uses multiple buckets to store data. This avoids read locks and greatly improves performance over a HashTable . Both are thread safe, but there are obvious performance wins with ConcurrentHashMap .


12 Answers

Synchronized HashMap

  1. Each method is synchronized using an object level lock. So the get and put methods on synchMap acquire a lock.

  2. Locking the entire collection is a performance overhead. While one thread holds on to the lock, no other thread can use the collection.

ConcurrentHashMap was introduced in JDK 5.

  1. There is no locking at the object level,The locking is at a much finer granularity. For a ConcurrentHashMap, the locks may be at a hashmap bucket level.

  2. The effect of lower level locking is that you can have concurrent readers and writers which is not possible for synchronized collections. This leads to much more scalability.

  3. ConcurrentHashMap does not throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it.

This article Java 7: HashMap vs ConcurrentHashMap is a very good read. Highly recommended.

like image 122
Joey.zhgw Avatar answered Oct 03 '22 08:10

Joey.zhgw


The short answer:

Both maps are thread-safe implementations of the Map interface. ConcurrentHashMap is implemented for higher throughput in cases where high concurrency is expected.

Brian Goetz's article on the idea behind ConcurrentHashMap is a very good read. Highly recommended.

like image 22
trshiv Avatar answered Oct 03 '22 07:10

trshiv


ConcurrentHashMap is thread safe without synchronizing the whole map. Reads can happen very fast while write is done with a lock.

like image 27
fastcodejava Avatar answered Oct 03 '22 06:10

fastcodejava


We can achieve thread safety by using both ConcurrentHashMap and synchronisedHashmap. But there is a lot of difference if you look at their architecture.

  1. synchronisedHashmap

It will maintain the lock at the object level. So if you want to perform any operation like put/get then you have to acquire the lock first. At the same time, other threads are not allowed to perform any operation. So at a time, only one thread can operate on this. So the waiting time will increase here. We can say that performance is relatively low when you are comparing with ConcurrentHashMap.

  1. ConcurrentHashMap

It will maintain the lock at the segment level. It has 16 segments and maintains the concurrency level as 16 by default. So at a time, 16 threads can be able to operate on ConcurrentHashMap. Moreover, read operation doesn't require a lock. So any number of threads can perform a get operation on it.

If thread1 wants to perform put operation in segment 2 and thread2 wants to perform put operation on segment 4 then it is allowed here. Means, 16 threads can perform update(put/delete) operation on ConcurrentHashMap at a time.

So that the waiting time will be less here. Hence the performance is relatively better than synchronisedHashmap.

like image 30
Sumanth Varada Avatar answered Oct 03 '22 06:10

Sumanth Varada


SynchronizedMap and ConcurrentHashMap are both thread safe class and can be used in multithreaded application, the main difference between them is regarding how they achieve thread safety.

SynchronizedMap acquires lock on the entire Map instance , while ConcurrentHashMap divides the Map instance into multiple segments and locking is done on those.

enter image description here

enter image description here

like image 33
Joby Wilson Mathews Avatar answered Oct 03 '22 06:10

Joby Wilson Mathews


Both are synchronized version of HashMap, with difference in their core functionality and their internal structure.

ConcurrentHashMap consist of internal segments which can be viewed as independent HashMaps Conceptually. All such segments can be locked by separate threads in high concurrent executions. So, multiple threads can get/put key-value pairs from ConcurrentHashMap without blocking/waiting for each other. This is implemented for higher throughput.

whereas

Collections.synchronizedMap(), we get a synchronized version of HashMap and it is accessed in blocking manner. This means if multiple threads try to access synchronizedMap at same time, they will be allowed to get/put key-value pairs one at a time in synchronized manner.

like image 42
Ashraf.Shk786 Avatar answered Oct 03 '22 08:10

Ashraf.Shk786


ConcurrentHashMap uses finer-grained locking mechanism known as lock stripping to allow greater degree of shared access. Due to this it provides better concurrency and scalability.

Also iterators returned for ConcurrentHashMap are weakly consistent instead of fail fast technique used by Synchronized HashMap.

like image 33
rai.skumar Avatar answered Oct 03 '22 07:10

rai.skumar


Methods on SynchronizedMap hold the lock on the object, whereas in ConcurrentHashMap there's a concept of "lock striping" where locks are held on buckets of the contents instead. Thus improved scalability and performance.

like image 42
Renukeswar Avatar answered Oct 03 '22 07:10

Renukeswar


ConcurrentHashMap :

1)Both maps are thread-safe implementations of the Map interface.

2)ConcurrentHashMap is implemented for higher throughput in cases where high concurrency is expected.

3) There is no locking in object level.

Synchronized Hash Map:

1) Each method is synchronized using an object level lock.

like image 44
NarayanaReddy Avatar answered Oct 03 '22 08:10

NarayanaReddy


ConcurrentHashMap allows concurrent access to data. Whole map is divided into segments.

Read operation ie. get(Object key) is not synchronized even at segment level.

But write operations ie. remove(Object key), get(Object key) acquire lock at segment level. Only part of whole map is locked, other threads still can read values from various segments except locked one.

SynchronizedMap on the other hand, acquire lock at object level. All threads should wait for current thread irrespective of operation(Read/Write).

like image 32
Vino Avatar answered Oct 03 '22 07:10

Vino


A simple performance test for ConcurrentHashMap vs Synchronized HashMap . The test flow is calling put in one thread and calling get in three threads on Map concurrently. As @trshiv said, ConcurrentHashMap has higher throughput and speed for whose reading operation without lock. The result is when operation times is over 10^7, ConcurrentHashMap is 2x faster than Synchronized HashMap.

like image 27
liaoming Avatar answered Oct 03 '22 08:10

liaoming


Synchronized HashMap

  1. Lock mechanism - It Locks the whole map, so Multiple threads can't access the map concurrently. So, performance is relatively less.

2.Null key or Value - It will allow null as a key or value.

3.Concurrent modification exception - Iterator return by synchronized map throws concurrent modification exception

ConcurrentHashMap

1.Lock mechanism -Locks the portion, Concurrent hashmap allows concurrent read and write. So performance is relatively better than a synchronized map

2.Null key or Value - It doesn't allow null as a key or value. If you use it will throw java.lang.NullPointerException at Runtime.

3.Concurrent modification exception - It doesn't throw concurrent modification exceptions.

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

public class Ex_ConcurrentHashMap {

    public static void main(String[] args) {
        
        Map<String, String> map = new ConcurrentHashMap<>();
        map.put("one", "one");
        map.put("two", "two");
        map.put("three", "three");
        System.out.println("1st  map : "+map);
        String key = null;
        for(Map.Entry<String, String> itr : map.entrySet())
        {
            key = itr.getKey();
            if("three".equals(key))
            {
                map.put("FOUR", "FOUR");
            }
            System.out.println(key+" ::: "+itr.getValue());
        }
        System.out.println("2nd  map : "+map);
        //map.put("FIVE", null);//java.lang.NullPointerException
        map.put(null, "FIVE");//java.lang.NullPointerException
        System.out.println("3rd  map : "+map);
    }
}

enter image description here

Synchronized HashMap Example

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

public class Ex_Synchronizedmap {

    public static void main(String[] args) {
        
        Map<String, String> map = new HashMap<>();
        
        map.put("one", "one");
        map.put("two", "two");
        map.put("three", "three");
        map.put("FOUR", null);
        map.put(null, "FIVE");
        
        System.out.println("map : "+map);
        
        Map<String, String> map1 = 
                Collections.synchronizedMap(map);
        System.out.println("map1 : "+map1);
        
        String key = null;
        for(Map.Entry<String, String> itr : map1.entrySet())
        {
            key = itr.getKey();
            if("three".equals(key))
            {
                map1.put("ABC", "ABC");
            }
            System.out.println(key+" ::: "+itr.getValue());
        }
        
        System.out.println("New Map :: "+map1);
        
        
        
        Iterator<Entry<String, String>> iterator = map1.entrySet().iterator();
        int i = 0;
        while(iterator.hasNext())
        {
            if(i == 1)
            {
                map1.put("XYZ", "XYZ");
            }
            Entry<String, String> next = iterator.next();
            System.out.println(next.getKey()+" :: "+next.getValue());
            i++;
        }
    }

}

enter image description here

like image 1
Sankarasai Avatar answered Oct 03 '22 07:10

Sankarasai