SoFunction
Updated on 2025-03-08

Implementation of ConcurrentHashMap in Java

ConcurrentHashMap (CHM for short) was newly introduced in Java 1.5 as an alternative to Hashtable and is an important member of the concurrent package. Before Java 1.5, if you want to implement a map that can be used safely in multi-threaded and concurrent programs, you can only choose from HashTable and synchronized Map, because HashMap is not thread-safe. But after introducing CHM, we have a better choice. CHM is not only thread-safe, but also performs better than HashTable and synchronizedMap. Compared with HashTable and synchronizedMap, the entire map is locked, and CHM only locks some maps. CHM allows concurrent read operations while maintaining data integrity during write operations through synchronous locks. We have learned the basics of CHM in Top 5 Java Concurrent Collections from JDK 5 and 6. In this blog I will introduce the following points:

  1. How to implement CHM in Java
  2. Under what circumstances should CHM be used
  3. Example of using CHM in Java
  4. Some important features of CHM

Implementation of ConcurrentHashMap in Java

CHM introduces segmentation and provides all the features supported by HashTable. In CHM, multithreading is supported to read Map and does not require any blocking. This is due to the fact that CHM splits the Map into different parts, locking only part of it when performing the update operation. According to the default concurrency level, the map is divided into 16 parts and is controlled by different locks. This means that up to 16 write threads can operate the Map at the same time. Just imagine that from only one thread entering to 16 write threads entering at the same time (read threads are almost unlimited), the performance improvement is obvious. However, since some update operations, such as put(), remove(), putAll(), and clear(), only lock the operation, the search operation cannot guarantee that the latest results will be returned.

Another important point is that when iterating over CHM, the iterator returned by keySet is weakly consistent and fail-safe, and may not return some recent changes. During the traversal, if the content on the array that has been traversed changes, the ConcurrentModificationExceptoin exception will not be thrown.

The default concurrency level of CHM is 16, but it can be changed by a constructor when creating CHM. There is no doubt that the concurrency level represents the number of concurrent update operations, so if only a few threads will update the map, it is recommended to set a low concurrency level. In addition, CHM also uses ReentrantLock to lock segments.

Example of ConcurrentHashMap putifAbsent method in Java

Many times we want to insert elements when they do not exist, and we usually write code like the following

synchronized(map){
 if ((key) == null){
  return (key, value);
 } else{
  return (key);
 }
}

The above code is easy to use in HashMap and HashTable, but there is a risk of errors in CHM. This is because CHM does not lock the entire Map during put operation, so when one thread is put(k,v), another thread calls get(k) and get null, which will cause the value of one thread put to be overwritten by the value of another thread put. Of course, you can encapsulate the code into a synchronized code block, which will make your code single-threaded, although thread-safe. The putIfAbsent(key,value) method provided by CHM implements the same function atomically, while avoiding the risk of thread competition above.

When to use ConcurrentHashMap

CHM is suitable for when the number of readers exceeds the number of readers, and when the number of readers is greater than or equal to the reader, the performance of CHM is lower than that of Hashtable and synchronized Map. This is because when the entire map is locked, the read operation waits for the thread that performs the write operation to the same part to end. CHM is suitable for making cache, initialized at the start of the program, and can then be accessed by multiple requesting threads. As Javadoc explains, CHM is a good alternative to HashTable, but remember that CHM has slightly less synchronization than HashTable.

Summarize

Now we know what ConcurrentHashMap is and when to use ConcurrentHashMap. Let’s review some key points of CHM.

  1. CHM allows concurrent read and thread-safe update operations
  2. When performing a write operation, CHM locks only part of the Map
  3. Concurrent updates are implemented by internally splitting the map into small parts according to the concurrency level.
  4. A high concurrency level will cause waste of time and space, while a low concurrency level will cause competition among threads when there are many threads written.
  5. All operations of CHM are thread-safe
  6. The iterator returned by CHM is weak consistency, fail-safe and does not throw a ConcurrentModificationException exception
  7. CHM does not allow null key values
  8. You can use CHM instead of HashTable, but remember that CHM will not lock the entire Map

The above are the implementation and usage scenarios of CHM in Java, I hope it can help everyone! Thank you for your support to this site!