ConcurrentHashMap && Hashtable#
How does ConcurrentHashMap achieve thread safety?#
Implementation in JDK1.5#
Uses
Segment (extends ReentrantLock)
to implement
By usingsegmented locking technique
, ConcurrentHashMap locks the storage in segments, then assigns a lock (segment) to each segment of data. When one thread occupies a lock (segment) to access a segment of data, other segments can still be accessed by other threads. By default, it allocates 16 segments, which improves efficiency by 16 times compared to Hashtable.
Implementation in JDK1.8#
Uses
CAS
andsynchronized
to ensure concurrent safety
The implementation in JDK8 also follows the idea of lock separation, dividing locks into finer segments thansegments (JDK1.5)
. As long as there is no hash collision, there will be no concurrent lock acquisition. It first uses the lock-free operationCAS
to insert the head node. If the insertion fails, it indicates that another thread has already inserted the head node, and it loops to perform the operation again (similar to a spin lock). If the head node already exists, itacquires the head node lock through synchronized
for subsequent operations, further improving performance compared to segment locks.
Hashtable#
Hashtable is also a thread-safe key-value data structure.
Comparison with HashMap:#
- Hashtable has been available since JDK1.0, while HashMap was introduced in JDK1.2.
- Hashtable inherits from the Dictionary class (deprecated), while HashMap inherits from the AbstractMap class.
- Hashtable does not support null keys or null values, whereas in HashMap, null can be used as a key, but only one such key is allowed; there can be one or more keys corresponding to null values.
- Hashtable is thread-safe, as every method includes the Synchronize method, while HashMap is not thread-safe.
- Both Hashtable and HashMap use Iterator, but due to historical reasons, Hashtable also uses Enumeration.
- The default initial size of Hashtable is 11, and each time it expands, the capacity becomes 2n+1 of the original. The default initial size of HashMap is 16, and each time it expands, the capacity doubles.
- The method of calculating hash values is different: Hashtable directly uses the object's hashCode, while HashMap also uses a perturbation function for processing.
Difference from Collections.synchronizedMap()#
synchronizedMap
is a private static inner class of Collections, which can be obtained through the Collections.synchronizedMap(Map)
method and upcast to a Map object.
Comparative analysis:
- Hashtable locks all methods using the synchronized keyword.
- There is an Object type mutex member, and the synchronize keyword is used to lock the mutex for thread-safe methods.