ConcurrentHashMap

Copyright statement: This article is an original article by the blogger and may not be reproduced without the blogger's permission. http://www.cnblogs.com/jokermo/

HashMap under high concurrency

1.ReHash

Rehash is a step in the expansion of HashMap. The length of Hashmap is limited, and data is continuously inserted. When the hashmap reaches a certain saturation, the probability of hash conflict will increase. At this time, the hashmap needs to be expanded, that is, Resize.

There are two factors that affect the occurrence of Resize:

1.Capacity

The current length of the HashMap. The length of the HashMap is a power of 2.

2.LoadFactor

HashMap load factor, the default value is 0.75f.

The conditions for measuring whether HashMap is resized are as follows:

HashMap.Size   >=  Capacity * LoadFactor

The Java code of ReHash is as follows:

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    for (Entry<K,V> e : table) {
        while(null != e) {
            Entry<K,V> next = e.next;
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity);
            e.next = newTable [i];
            newTable [i] = e;
            e = next;
        }
    }
}

. The Resize of Hashmap includes two steps: expansion and ReHash. ReHash may form a linked list ring in the case of concurrency. So HashMap cannot be used for multithreading

Multithreaded ConcurrentHashMap

 ConcurrentHashMap can be said to be a secondary hash table. In a general hash table, there are several sub-hash tables. The sub hash table can be called segment, and the structure of ConcurrentHashMap is as follows:

At this time, the ConcurrentHashMap adopts the lock segmentation technology, and the read and write operations of each segment are highly autonomous, and the segments do not affect each other.

 There are three cases of high concurrent read and write operations in ConcurrentHashMap:

  • Concurrent writes to the same segment
  • Concurrent writes to different segments
  • Read and write the same segment

Segment writes need to be locked, so concurrent writes to the same segment will be blocked.

It can be seen that each segment in the ConcurrentHashMap holds a lock. While ensuring thread safety, the granularity of the lock is reduced, making concurrent operations more efficient.

 The reading and writing process of ConcurrentHashMap:

Get method:

1. Do Hash operation for the input Key to get the hash value.

2. Through the hash value, locate the corresponding Segment object

3. Through the hash value again, locate the specific position of the array in the Segment.

Put method:

1. Do Hash operation for the input Key to get the hash value.

2. Through the hash value, locate the corresponding Segment object

3. Acquire a reentrant lock

4. Through the hash value again, locate the specific position of the array in the Segment.

5. Insert or overwrite the HashEntry object.

6. Release the lock.

size method

The Size method of ConcurrentHashMap is a nested loop, and the general logic is as follows:

1. Traverse all segments.

2. Accumulate the number of elements of Segment.

3. Accumulate the modification times of Segment.

4. Determine whether the total modification times of all segments is greater than the previous total modification times. If it is greater than that, it means that there is a modification in the statistical process, re-count, and the number of attempts +1; if not. The description has not been modified, and the statistics are over.

5. If the number of attempts exceeds the threshold, each segment is locked and counted again.

6. Judge again whether the total modification times of all segments is greater than the previous total modification times. Since it has been locked, the number of times must be equal to the last time.

7. Release the lock and the statistics are over.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325528406&siteId=291194637