The principle of Hashtable, HashMap, ConcurrentHashMap of java container

HashMap

  • Non-thread safe container
  • Internally maintain a hash table (array)
    key through hash algorithm & array length to obtain the index of the hash table array

hash algorithm

static final int hash(Object key) {
   int h;
   return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

Here, the hash value of the key and the hash value are shifted to the right by 16 bits to perform an OR operation (rich low-order randomness). The purpose is to increase the collision probability of the hash value status when the hash is greater than 2 to the 16th power (because the hash rate is too high when the hash value is too high), some people test this method can reduce the collision probability by 10%.
After getting the hsah value, get the index of the hash table like this
(n-1) & hash // discard the low order of the hash table to get an index less than the length of the array (n: array length, the maximum index of the array is always 2n-1, binary is valid Bit is always 1 good low bit mask )

Detailed hash operation of hashMap

Hash table

What to do when the mask operation of the hash table collides? It does not matter default hash table is stored in a doubly linked list
will continue to insert data into the tail of the list when a collision occurs


But retrieving data when the linked list is too long can be a problem.
So when the length of the linked list is greater than 8, hashMap expands a balanced tree structure. Red-black tree
retrieval efficiency of the tree structure is much higher
but will retain the linked list structure why? To forEach. . . .

Hash table expansion

The default initial length of the hash table is 16, and the initial length can be specified through the constructor (the actual length of the linked list will be automatically calculated according to the input length and a suitable length is selected)

/**
  * 这里的代码有时间在做深度研究
  * Returns a power of two size for the given target capacity.
  */
 static final int tableSizeFor(int cap) {
     int n = cap - 1;
     n |= n >>> 1;
     n |= n >>> 2;
     n |= n >>> 4;
     n |= n >>> 8;
     n |= n >>> 16;
     return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
 }

When the number of data within the hash table will be expansion greater than 16 * 0.75 * 2 each time (can be specified)
when the hash table is larger than MIN_TREEIFY_CAPACITY = 64; This value, the table can be the tree of the tub
or tub Will expand when there are too many elements instead of tree


Hashtable

  • Thread safety (implemented by synchronized locks)
  • The internal structure is similar to hashMap hash table + linked list, but there is no red-black tree upgrade in jdk8. It may be that the serial thread-safe container such as hashTable has been abandoned. ConcurrentHashMap has an absolute advantage over it.

ConcurrentHashMap

  • Thread-safe
  • The internal storage structure is roughly the same as hashMap (jdk8 was previously a segmented lock)
  • Use cas (compare and replace) + volatile + synchronized keywords to achieve safe concurrency
  • The use of synchronized is rarely used only when operating on a single linked list on the table (only excluding other changes (remove || put) does not affect get)
  • Pessimistic locks and optimistic locks:
    pessimistic locks means that if a thread occupies a lock and causes all other threads that need the lock to wait until the lock is released, in other words, the lock is monopolized. It is synchronized; optimistic locking means that the operation does not lock, but performs an operation with the attitude of trying. If the operation fails or the operation conflicts, then enter the retry until the goal is achieved.
The hash value calculation is slightly different:
 static final int spread(int h) {
   return (h ^ (h >>> 16)) & HASH_BITS; // 生成一个 小于long int 最大值的hash
 }
For shallow reading of ConcurrentHashMap, only here

ConcurrentHashMap is complicated when it comes to concurrency. Post a separate post update

Published 17 original articles · won 24 · views 280,000 +

Guess you like

Origin blog.csdn.net/qq_22956867/article/details/79414338