Here we will be discussing out one by one individually then rolling onto the difference after having an adequate understanding of all three of them. We will be discussing ConcurrentHashMap first followed by HashTable, lastly followed by Synchronized Map. Let us start with ConcurrentHashMap first.
The underlying data structure for ConcurrentHashMap is HashTable. ConcurrentHashMap allows concurrent read and thread-safe update operations. To perform read operation thread won’t require any lock but to perform update operation thread require a lock, but it is the lock of only a particular part of Map(Bucket level lock). Instead of whole map concurrent update achieved by internally dividing the map into a smaller portion which is defined by concurrency level. The default concurrency level is 16 i.e ConcurrentHashMap allows simultaneously read and 16 write(update) operations. The value null is not allowed for both keys and values. While one thread is iterating the other thread can perform update operation and ConcurrentHashMap never throws ConcurrentModificationException.
Syntax:
ConcurrentHashMap<K,V> CHM = new ConcurrentHashMap<>();
The above constructor creates an empty ConcurrentHashMap with
- Default initial capacity equals 16
- Default fill ratio equals 0.75
- Default concurrency level 16 where K is key and V is the value of ConcurrentHashMap
Example:
Java
// Java program to illustrate ConcurrentHashMap // Importing required packages import java.io.*; import java.util.*; import java.util.concurrent.*; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Creating ConcurrentHashMap class object // Declaring object of integer an string type ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>(); // Adding entry to ConcurrentHashMap // Custom input entries chm.put( 65 , "A" ); chm.put( 66 , "B" ); // Print and display the ConcurrentHashMap System.out.println(chm); // Adding the entry if the given entry is not // present in the ConcurrentHashMap Custom input // entries chm.putIfAbsent( 67 , "C" ); chm.putIfAbsent( 68 , "D" ); // Printand display the ConcurrentHashMap System.out.println(chm); // Removing entry With Key and Value as 68 and D chm.remove( 68 , "D" ); // Print and display the ConcurrentHashMap System.out.println(chm); // Replacing Value of an entry chm.replace( 66 , "B" , "E" ); // Again, print and display the ConcurrentHashMap System.out.println(chm); } } |
{65=A, 66=B} {65=A, 66=B, 67=C, 68=D} {65=A, 66=B, 67=C} {65=A, 66=E, 67=C}
Now dwelling on the second concept that is HashTable. The underlying data structure for HashTable is HashTable. Insertion order in HashTable is not preserved, and it is based on the hashcode of keys. Duplicates keys are not allowed, but values can be duplicated. Heterogeneous objects are allowed for both keys and values. The value null is not allowed for both key and value otherwise we will get RunTimeException saying NullPointerException. It implements Serializable and cloneable interfaces but not RandomAccess. Every method inside it is synchronized and hence HashTable objects are thread-safe. HashTable is the best choice if our frequent operation is search operation.
Syntax:
Hashtable<K,V> ht = new Hashtable<>();
The above constructor creates an empty hashtable object with an initial default capacity of 11 and a default fill ratio of 0.75. Where K is key and V is the value of a hashtable.
Example:
Java
// Java program to illustrate HashTable // Importing required packages import java.io.*; import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating Hashtable object Hashtable<Integer, String> ht = new Hashtable<>(); // Adding entry to Hashtable // Custom input entries ht.put( 65 , "A" ); ht.put( 66 , "B" ); ht.put( 67 , "C" ); ht.put( 68 , "D" ); // Print and display the HashTable elements System.out.println(ht); } } |
{65=A, 68=D, 67=C, 66=B}
Lastly, discussing out Synchronized Map before landing upon conclusive differences between all three of them. The synchronizedMap() method is used to return a synchronized(thread-safe) map backed by the specified map. This method is present in java.util.Collections.
Syntax:
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> M) // where M is the map to be synchronized K is key // and V is value for the resultant synchronized map.
Example:
Java
// Java program to demonstrate synchronizedMap() method // Importing required packages import java.io.*; import java.util.*; // Main class public class GFG { // Main driver method public static void main(String[] args) { // Try block to check for exceptions try { // Creating object of HashMap // Declaring object of integer and string type HashMap<Integer, String> map = new HashMap<>(); // Adding entry to map object created above // Custom input entries map.put( 65 , "A" ); map.put( 66 , "B" ); map.put( 67 , "C" ); map.put( 68 , "D" ); // Print and display the map object System.out.println( "Map is " + map); // Creating a synchronized map object // Declaring object of type integer and string Map<Integer, String> synmap = Collections.synchronizedMap(map); // Print and display the synchronized map // elements System.out.println( "Synchronized map is : " + synmap); } // Catch block to handle the exceptions catch (IllegalArgumentException e) { // Display the exception on the console System.out.println(e); } } } |
Map is {65=A, 66=B, 67=C, 68=D} Synchronized map is : {65=A, 66=B, 67=C, 68=D}
By far we have discussed enough the concepts along with internal working through implementation in the programs. Let us finally conclude out the differences between them to get a tight grip to understand the minute difference between them.
ConcurrentHashMap | SynchronizedMap | HashTable |
---|---|---|
We will get thread safety without locking the total map object just with a bucket level lock. | We will get thread safety by locking the whole map object. | We will get thread safety by locking the whole map object |
At a time multiple threads are allowed to operate on map objects safely. | At a time only one thread is allowed to perform any operation on a map object. | At a time one thread is allowed to operate on a map object. |
Read operation can be performed without lock but write operation can be performed with bucket level lock. | Every read and write operations required total map object | Every read and write operations required total map object |
While one thread iterating map objects the other thread is allowed to modify the map and won’t get ConcurrentModificationException. | While one thread iterating map object the other threads are not allowed to modify the map otherwise we will get ConcurrentModificationException | While one thread iterating map object the other threads are not allowed to modify the map otherwise we will get ConcurrentModificationException |
Iterator of ConcurrentHashMap is fail-safe and won’t raise ConcurrentModificationException | Iterator of SynchronizedMap is fail-fast and it will raise ConcurrentModificationException | Iterator of HashTable is fail-fast and it will raise ConcurrentModificationException |
Null is not allowed for both keys and values. | Null is allowed for both keys and values | Null is not allowed for both keys and values. |
Introduce in java 1.5version | Introduce in java 1.2 version | Introduce in java 1.0version |