Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace ConcurrentHashMap with EnumMap

Tags:

java

All the while, I am using ConcurrentHashMap, if I want to achieve the following.

  1. Able to iterate the map without throwing ConcurrentModificationException, while another thread is modifying the map content.
  2. Allow two modification, by two threads at the same time.

Sometime, I use enum as key, and from EnumMap Javadoc, I realize,

Iterators returned by the collection views are weakly consistent: they will never throw ConcurrentModificationException and they may or may not show the effects of any modifications to the map that occur while the iteration is in progress.

Hence, is it safe for me to replace

Map<Country, String> map =  new ConcurrentHashMap<Country, String>();

with

Map<Country, String> map =  Collections.synchronizedMap(new EnumMap<Country, String>(Country.class));

I know there is no putIfAbsent in EnumMap, but that is OK for me at this moment as I do not require it.

like image 421
Cheok Yan Cheng Avatar asked Jan 16 '11 04:01

Cheok Yan Cheng


People also ask

Why EnumMap is faster than HashMap?

EnumMap is much faster than HashMap. All keys of each EnumMap instance must be keys of the same enum type. EnumMap doesn't allow inserting null key if we try to insert the null key, it will throw NullPointerException. EnumMap is internally represented as arrays therefore it gives the better performance.

Is EnumMap thread-safe?

Java EnumMap is not thread-safe. You can make thread-safe by doing Collections.

Can we put null key in ConcurrentHashMap?

Inserting null objects is not possible in ConcurrentHashMap as a key or value.

What is difference between collection synchronizedMap map and ConcurrentHashMap?

This is because the Collections. synchronizedMap() requires each thread to acquire a lock on the entire object for both read/write operations. By comparison, the ConcurrentHashMap allows threads to acquire locks on separate segments of the collection, and make modifications at the same time.


1 Answers

You can't do it for two reasons:

  1. Lack of synchronization may cause memory visibility effects (since iterators of Collections.synchronizedMap are not synchronized).
  2. Contract of Iterator would be broken - you may get NoSuchElementException when calling next() after hasNext() returned true.
like image 82
axtavt Avatar answered Nov 10 '22 12:11

axtavt