Thursday, August 25, 2016

How ConcurrentHashMap Internally Works in Java.

The ConcurrentHashMap is very similar to the HashMap class, except that ConcurrentHashMap offers internally maintained concurrency. It means you do not need to have synchronized blocks when accessing ConcurrentHashMap in multithreaded application.
The only thread safe collection objects were Hashtable and synchronized Map prior to JDK 5.

Why we need ConcurrentHashMap when we already had Hashtable?
HashTable allows us to access Map.Entries objects by locking the entire map, may it be a read or update or delete. Which means thread wait time to perform an operation on HashTable is longer. This leads to an overhead when we have a heavily loaded application.
ConcurrentHashMap resolves this issue by not obtaining lock on the entire map, but locking the segments.

How ConcurrentHashMap works in Java
According to ConcurrentHashMap Oracle docs,
The constructor of ConcurrentHashMap looks like this :
public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel)

The constructor of ConcurrentHashMap uses the below three parameters:
initialCapacity – the initial capacity. The implementation performs internal sizing to accommodate this many elements.
loadFactor – the load factor threshold, used to control resizing. Resizing may be performed when the average number of elements per bin exceeds this threshold.
concurrencyLevel – the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this many threads.

The default value of initialCapacity and concurrencyLevel is 16. Which means ConcurrentHashMap has 16 locks by default which is acquired on 16 buckets. If one thread acquired a lock on one bucket, we can have 16 concurrent threads working on one ConcurrentHashMap at the same time. It doesn’t lock the entire map. As per Javadocs, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.

Can two threads update the ConcurrentHashMap simultaneously?
Yes it is possible that two threads can simultaneously write on the ConcurrentHashMap. ConcurrentHashMap default implementation allows 16 threads to read and write in parallel.
But in the worst case scenario, when two objects lie in the same segment or same partition, then parallel write would not be possible.

Does ConcurrentHashMap Iterator behave like fail fast iterator or fail safe Iterator?
ConcurrentHashMap iterator behaves like fail safe iterator. It will not throw ConcurrentModificationException.

Can multiple threads read from the Hashtable concurrently?
No multiple threads cannot read simultaneously from Hashtable. Reason, the get() method of  Hashtable is synchronized. As a result, at a time only one thread can access the get() method .
It is possible to achieve full  concurrency for reads (all the threads read at the same time) in  ConcurrentHashMap by using volatile keyword.



Drawbacks of ConcurrentHashMap
ConcurrentHashMap doesn’t lock the entire collection while performing modification. So, it may not provide accurate information about its size using size() operation.

putIfAbsent() method in ConcurrentHashMap
If a key is not associated with a value, it can be associated with a value with following logic :
if (!map.containsKey(key))
       return map.put(key, value);
     else
       return map.get(key);

But, when multiple threads access this, this won’t work as expected.
For this, ConcurrentHashMap provides a putIfAbsent() method that associates the key with a value if not already associated.
  
replace() method in ConcurrentHashMap
If we need to replace the value for an existing key, we can normally do so with following code :
     if (map.containsKey(key)) {
       return map.put(key, value);
     }
However, in multithreaded environment, this can lead to race condition.
 For this, ConcurrentHashMap provides a method replace() to replace the value for an existing key.
 We can use it as follows : map.replace(key, value);
  
Summary of ConcurrentHashMap features
·         ConcurrentHashMap is similar to Hashtable, but performs better in a multi-threaded environment as it does not block itself to be access by a single thread.
·         It does not allow duplicate keys.
·         It does not allow null to be used as a key or value.
·         Iterators of ConcurrentHashMap don’t throw a ConcurrentModificationException, so we don’t need to lock the collection while iterating it.


No comments:

Post a Comment