The underlying implementation of HashMap, HashTable and ConcurrentHashMap in Java

1. The underlying implementation of HashMap

In JDK1.6 and JDK1.7, HashMap is implemented by bit bucket + linked list , that is, using linked list to handle conflicts, linked lists with the same hash value are stored in one linked list. However, when there are many elements in a bucket, that is, when there are many elements with equal hash values, the efficiency of searching sequentially by key value is low.
write picture description here
In JDK1.8, HashMap is implemented by bit bucket + linked list + red-black tree . When the length of the linked list exceeds the threshold (8), the linked list is converted into a red-black tree, which greatly reduces the search time. The source code of HashMap is optimized in java jdk8. In jdk7, when HashMap handles "collision", it is stored in a linked list. When there are many collision nodes, the query time is O(n). In jdk8, HashMap adds a data structure of red-black tree to deal with "collision". When there are few collision nodes, linked list storage is used. When it is large (>8), red-black tree is used (characterized by query time is O(logn)) storage (there is a threshold control, greater than the threshold (8), the linked list storage is converted into a red-black tree storage)
write picture description here

Briefly talk about the implementation principle of HashMap:

First of all, there is an array where each element is a linked list (may be inaccurate), when adding an element (key-value), the hash value of the element key is first calculated to determine the insertion position in the array, but there may be The elements of the same hash value have been placed in the same position of the array, and then they are added to the back of the elements of the same hash value. They are in the same position of the array, but form a linked list. The hash values ​​on the same linked list are the same. So arrays store linked lists. When the length of the linked list is too long, the linked list is converted into a red-black tree, which greatly improves the efficiency of search.

Second, the underlying implementation of HashTable

write picture description here
(01) Hashtable inherits from Dictionary class and implements Map interface. Map is a "key-value key-value pair" interface, and Dictionary is an abstract class that declares an operational "key-value pair" functional interface. Relying on synchronized to achieve synchronization
(02) Hashtable is a hash table implemented by the "zipper method". It includes several important member variables: table, count, threshold, loadFactor, modCount.
  table is an Entry[] array type, and Entry is actually a singly linked list. The "key-value pairs" of the hash table are stored in the Entry array.
  count is the size of the Hashtable, which is the number of key-value pairs that the Hashtable holds.
  threshold is the threshold of Hashtable, which is used to judge whether the capacity of Hashtable needs to be adjusted. The value of threshold = "capacity * load factor".
  loadFactor is the load factor.
  modCount is an instance of Hashtable used to implement the fail-fast mechanism. There are two parameters that affect its performance: initial capacity and load factor. The capacity is the number of buckets in the hash table, and the initial capacity is the capacity when the hash table was created. Note that the state of the hash table is open: in the case of a "hash collision", a single bucket stores multiple entries, which must be searched in order. The load factor is a measure of how full a hash table can become before its capacity is automatically increased. The two parameters initial capacity and load factor are only hints to the implementation. The exact details of when and if the rehash method is called is implementation-dependent. Typically, the default load factor is 0.75, which seeks a compromise between time and space costs. A high load factor reduces space overhead, but it also increases the time to find an entry (reflected in most Hashtable operations, including get and put operations).

3. The underlying implementation of ConcurrentHashMap

write picture description here
write picture description here
ConcurrentHashMap adopts the mechanism of segment lock to implement concurrent update operations. The bottom layer is composed of Segment array and HashEntry array. Segment inherits ReentrantLock to act as a lock, so it is a kind of reentrant lock (ReentrantLock), in which each Segment object guards several buckets of each hash map. HashEntry is used to encapsulate the key/value pairs of the mapping table; each bucket is a linked list linked by several HashEntry objects, and a ConcurrentHashMap instance contains an array of several Segment objects (in terms of the default ConcurrentLeve of 16, In theory, 16 threads are allowed to execute concurrently)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326916823&siteId=291194637