ConcurrentHashMap vs Collections.synchronizedMap()

Summary

ConcurrentHashMap and Collections.synchronizedMap() both provide thread-safe collection operations for multithreaded environments. A key distinction lies in their locking strategies: ConcurrentHashMap locks only specific data segments during updates, allowing higher concurrency, whereas Collections.synchronizedMap() locks the entire map, limiting concurrent access. Furthermore, ConcurrentHashMap does not guarantee element order but prevents ConcurrentModificationException during concurrent iteration and updates, unlike Collections.synchronizedMap() which preserves order but is susceptible to this exception. For developers requiring both order preservation and protection against ConcurrentModificationException, ConcurrentSkipListMap, available since Java 1.6, provides a viable solution, albeit with potential performance considerations.

ConcurrentHashMap and Collections.synchronizedMap() both provide thread-safe operations of collections of data. They are used in multithreaded programs to provide both thread safety and performance improvements. In many cases, we can use either of them.

But the realization of thread safety is different for these two implementations. ConcurrentHashMap will create an HashEntry[] array internally to store the elements passed in from a Map, while Collections.synchronizedMap() will return a SynchronizedMap.

The main difference between these two is that ConcurrentHashMap will lock only portion of the data which are being updated while other portion of data can be accessed by other threads. However, Collections.synchronizedMap() will lock all the data while updating, other threads can only access the data when the lock is released. If there are many update operations and relative small amount of read operations, you should choose ConcurrentHashMap.

Also one other difference is that ConcurrentHashMap will not preserve the order of elements in the Map passed in. It is similar to HashMap when storing data. There is no guarantee that the element order is preserved. While Collections.synchronizedMap(0 will preserve the elements order of the Map passed in. For example, if you pass a TreeMap to ConcurrentHashMap, the elements order in the ConcurrentHashMap may not be the same as the order in the TreeMap, but Collections.synchronizedMap() will preserve the order.

Furthermore, ConcurrentHashMap can guarantee that there is no ConcurrentModificationException thrown while one thread is updating the map and another thread is traversing the iterator obtained from the map. However, Collections.synchronizedMap() is not guaranteed on this. If we obtain an Iterator from Collections.synchronizedMap() by calling map.keySet().iterator() and then traverse the iterator, at the same time if another thread is trying to updating the map by calling map.put(K,V), we will get a ConcurrentModificationException.

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

map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");

Set<Entry<String,String>> entries = map.entrySet();

Iterator<Entry<String,String>> iter = entries.iterator();

while(iter.hasNext()){
	System.out.println(iter.next()); //Will throw ConcurrentModificationException
	map.remove("key2");  
}

Now I am wondering whether there is one object which can preserve the insertion order of elements like Collections.synchronizedMap() and also doesn't throw ConcurrentModificationException like ConcurrentHashMap. Fortunately since 1.6 there is a class called ConcurrentSkipListMap which can fulfill these two requirements, from the documentation, we can find that ConcurrentSkipListMap will not throw ConcurrentModificationException and also it will preserve the insertion order of the Map passed in. The only drawback it may have is its performance.

You can also check the difference between ConcurrentHashMap and Hashtable for more understanding about ConcurrentHashMap.

CONCURRENTHASHMAP COLLECTIONS.SYNCHRONIZEDMAP

  RELATED

  COMMENT

1
nits
Feb 8, 2016 at 7:43 am

ConcurrentSkipListMap does not preserved insertion order.

It provides only sorting and concurrency.