32 Differences Between Thread Safe Concurrent Hash Map and Hashtable

32 Differences Between Thread-Safe ConcurrentHashMap and Hashtable #

In this lesson, let’s discuss the differences between ConcurrentHashMap and Hashtable, both of which are thread-safe.

As we know, HashMap is not thread-safe. However, ConcurrentHashMap and Hashtable are both thread-safe. So what are the differences between them? Let’s analyze them from the following four aspects.

Different versions of appearance #

Let’s start by analyzing the obvious appearance time. Hashtable has been around since JDK 1.0 and implemented the Map interface in JDK 1.2, making it a member of the collection framework. ConcurrentHashMap, on the other hand, appeared in JDK 1.5. Typically, what appears later is an optimization of what appeared earlier. Therefore, they also have significant differences in implementation and performance.

Different ways of implementing thread safety #

Although both ConcurrentHashMap and Hashtable are thread-safe, their implementation principles are different. Hashtable achieves concurrency safety through the use of the synchronized keyword. Let’s take the clear() method as an example:

public synchronized void clear() {
    Entry<?,?> tab[] = table;
    modCount++;
    for (int index = tab.length; --index >= 0; )
        tab[index] = null;
    count = 0;
}

It can be seen that the clear() method is synchronized. Similarly, other methods such as put, get, and size are also synchronized. Hashtable is thread-safe because almost every method is synchronized, which ensures thread safety.

The principle of Collections.SynchronizedMap(new HashMap()) is similar to Hashtable, also using synchronized. However, ConcurrentHashMap’s implementation principle is quite different. Let’s take a look at its structure diagram in Java 8:

img

We have already discussed and analyzed the detailed principles of ConcurrentHashMap in Lesson 30. Essentially, it achieves thread safety by using CAS + synchronized + Node, which is quite different from Hashtable’s complete reliance on synchronized.

Different performance #

Due to the differences in their implementation of thread safety, they also differ greatly in performance. As the number of threads increases, the performance of Hashtable dramatically decreases because each modification requires locking the entire object, making it inaccessible to other threads during that period. Moreover, it incurs additional overhead such as context switching. Therefore, its throughput is even lower than that of a single-threaded scenario.

In ConcurrentHashMap, even when locking occurs, it only locks a portion, not the entire object. Therefore, the throughput in multithreaded scenarios is usually greater than that in single-threaded scenarios. That is to say, ConcurrentHashMap has greatly improved the concurrency efficiency compared to Hashtable.

Different modifications during iteration #

Hashtable (including HashMap) does not allow modifications to its content during iteration; otherwise, it will throw the ConcurrentModificationException exception. The principle is to check the modCount variable in the next() method of the iterator. Here is the code:

public T next() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    return nextElement();
}

As can be seen in the next() method, it first checks whether modCount is equal to expectedModCount. expectedModCount is generated when the iterator is created and does not change. It represents the number of times the current Hashtable has been modified. Each time a method like addEntry(), remove(), or rehash() is called on Hashtable, the value of modCount will be modified. As a result, if we modify the entire content of Hashtable during iteration, it will also be reflected in modCount. In this way, the iterator can perceive it, and it will find that modCount is not equal to expectedModCount, and thus it will throw the ConcurrentModificationException exception.

Therefore, Hashtable does not allow modifications to its content during iteration. In contrast, even if ConcurrentHashMap modifies its content during iteration, it will not throw the ConcurrentModificationException.

This lesson summarizes the differences between ConcurrentHashMap and Hashtable. Although both are thread-safe, they differ significantly in versions of appearance, ways of implementing thread safety, performance, and whether modifications are supported during iteration. If we have concurrent scenarios, ConcurrentHashMap is the most appropriate choice. On the contrary, Hashtable is no longer recommended.