ConcurrentHashMap uses multiple buckets to store data. Since HashTable locks the whole map, ConcurrentHashMap does not come with a performance impact as seen in HashTable (due to having multiple locks at the segment level (sharding) rather than the object level). ConcurrentHashMap and HashTable are thread-safe. The main difference lies in their performance. ConcurrentHashMap has a good performance than HashTable.

I found a very helpful analogy online that says that HashTable provides the lock on the main door of your house, while ConcurrentHashMap locks each door within your house.

You cannot do compound operations on ConcurrentHashMap, but they are supported in HashTable (due to them having a lock on the whole map rather than a portion of it).  Here is an example:

We can also say that all the operations on the HashTable are simply synchronized.

HashTables were released quite early on but ConcurrentHashMaps were introduced in Java5+. The main objective was to enhance the performance while in multi-threaded environments. Never every use HashTable in a single threaded application. Also, try to avoid ConcurrentHashMap as well, but instead use HashMap only in a single-threaded application. In multi-threaded try to prefer ConcurrentHashMap over HashMap and the HashTable.

HashTable belongs to the Collection framework but ConcurrentHashMap is part of the Executor framework. HashTable also extended the old/obsolete Dictionary class.

As regard to iterators, HashTable iterators are fail-fast whereas iterators for ConcurrentHashMap are weakly consistent.

If we further compare ConcurrentHashMap with the Collections.synchronizedMap(mMap), we notice that ConcurrentHashMap allow concurrent modification from multiple threads while Collections.synchronizedMap(mMap) creates a blocking map (similar methodology to HashTable, and implemented with only one mutex). So, this is another pointer that when you need to have multiple threads doing concurrent modifications then prefer the ConcurrentHashMap over the other two variants. Also, if the focus is on high write efficiency rather than high read efficiency then use ConcurrentHashMap.

Another difference that we should note is that we cannot have null keys and null values in the ConcurrentHashMap, whereas synchronizedMap does support one null key and any number of null values.

There were some problems with huge memory consumption when thousands of threads were accessing ConcurrentHashMap entries. These sort of problems have been mostly resolved in the Java 7 and 8 version by smart handling of concurrency level and the load factor in ConcurrentHashMap.