2.Java Set-concurrenthashmap realization principle and Source code analysis

Source: Internet
Author: User

First, why use Concurrenthashmap

Using HashMap in concurrent programming can lead to a dead loop, while the use of thread-safe hashtable is inefficient.

   Thread insecure HashMap

In a multithreaded environment, a put operation using hashmap causes a dead loop, which results in a CPU utilization of nearly 100%, so it cannot be used in a concurrency scenario HashMap

  The inefficient Hashtable

Hashtable uses synchronized to keep threads safe, but Hashtable is inefficient in the event of intense online competition. When a thread accesses the Hashtable synchronization method, other methods access the Hashtable synchronization method, which can enter blocking or polling state. If thread 1 uses put for element addition, thread 2 cannot be added to the element with the put method, nor can the Get method be used to get the element, so the more intense the competition, the lower the efficiency.

  The lock segmentation Technology of Concurrenthashmap

Hashtable containers are inefficient in a highly competitive concurrency environment because all the threads that access Hashtable must compete for the same lock, and if the container has multiple locks, each lock is used to lock part of the data in the container, and when multiple threads access data from different data segments in the container, There is no lock contention between threads, which can effectively increase the concurrent access rate, which is the Concurrenthashmap lock segmentation technique. Divide the data into a section of storage, and then give each piece of data a lock, when a thread occupies a lock to access one of the data, other pieces of data can also be accessed by other threads.

Second, structure analysis

The main difference between Concurrenthashmap and Hashtable is the granularity of the lock and how it is locked, which can be easily understood as splitting a large hashtable into multiple, forming a lock separation

Feeling a segment is equivalent to a Hashtable

Second, the application scenario

When there is a large array that needs to be shared across multiple threads, consider whether to layer it to multiple nodes and avoid large locks. And we can consider some module location by hash algorithm.

In fact, not only for threading, when designing the data table of the transaction (transactional transaction in a sense is also the embodiment of the synchronization mechanism), you can think of a table as a need to synchronize the array, if the operation of the table data too much can consider the transaction separation (which is why to avoid large tables), such as the data for the field splitting, Level sub-table, etc.

Third, the source code interpretation

As can be seen, Concurrenthashmap is divided into a number of segment, each segment has a lock, and then each segment (Inherit Reentrantlock) below contains a number of Hashentry list data. For a key, it takes three times (why hash three times?). After explanation) hash operation, in order to finally locate the position of this element, the three hashes are:

1. For a key, first hash operation, get the hash value H1, that is H1 = Hash1 (key)

2. H1 the resulting high number of the second hash, get the hash value H2, that is, H2 = HASH2 (H1 high), through the H2 can determine which segment to put the element

3. A third hash of the resulting H1 is obtained, and the hash value is H3, i.e. H3=HASH3 (H1), which determines H3 can determine which hashentry the element is placed in

Note: In the use of key to locate segment before the hash operation, that is, the first hash, the main purpose of this hash is to reduce the hash conflict, so that the elements can be evenly distributed on different segment, so as to improve the container access efficiency. If the quality of the hash is poor to the pole, then all elements are in a segment, not only the access element is slow, the segmented lock loses its meaning.

  The characteristics of Concurrenthashmap core method

Concurrenthashmap allows multiple read operations to be performed concurrently, and read operations do not require locking. If you use traditional techniques, such as implementations in HashMap, if you allow the addition or deletion of elements in the middle of a hash chain, the read operation will get inconsistent data without locking. Concurrenthashmap's implementation technology is to ensure that hashentry is almost immutable, in order to ensure that the read operation can see the latest value, the value is set to volatile; The following is the structure of the Hashentry

Static Final class Hashentry<k,v> {  2.     Final K key;   3.     finalint  hash;   4.     volatile  V value;   5.     final hashentry<k,v> next;  

You can see that except that value is not final, the other values are final, which means that you cannot add or remove nodes from the middle or tail of the hash chain, because this requires modifying the reference value of next, and all the node modifications can only start from the head

For put operation, can be added to the head of the hash chain, but for the remove operation, it may be necessary to remove a node from the middle, which requires that all the nodes in front of the node to be deleted are copied over, and the last node points to the next one to delete the nodes. This is also described in detail when explaining the delete operation. To ensure that the read operation can see the most recent value, set the value to volatile, which avoids locking.

  

  Concurrenthashmap data members and their roles are explained:

1   Public classConcurrenthashmap<k, v>extendsAbstractmap<k, v>2          ImplementsConcurrentmap<k, v>, Serializable {3      /** 4 * Mask value for indexing into segments. The upper bits of a5 * key ' s hash code is used to choose the segment.6 */  7      Final intSegmentmask; 8 9      /** Ten * Shift value for indexing within segments. One */   A      Final intSegmentshift;  -  -      /**  the * The segments, each of which is a specialized hash table - */   -      FinalSegment<k,v>[] segments;  -}

All members are final, with Segmentmask and segmentshift primarily for locating segments

Final Segment<k,v> segmentfor (int  hash) {  2.     return segments[(hash >>> segmentshift) & Segmentmask];  

  

Each segment is equivalent to a small Hashtable, and its data members are as follows:

1.Static Final classSegment<k,v>extendsReentrantlockImplementsSerializable {2.Private Static Final LongSerialversionuid = 2249069246763182397L; 3./**4. * The number of elements in this segment ' s region. 5.*/6.transient volatile intcount; 7. 8./**9. * Number of updates that alter the size of the table.          This is 10.          * Used during Bulk-read methods to make sure they see a 11.          * Consistent snapshot:if modcounts change during a traversal 12.          * of segments computing size or checking containsvalue, then 13.          * We might have a inconsistent view of state so (usually) 14. * Must retry. A.*/16.transient intModcount; 17. 18./*** The table is rehashed when its size exceeds this threshold.          * (The value of this field was always <tt> (int) (capacity * 21). * loadfactor) </tt>.) .*/23.transient intthreshold; 24. 25./*** the Per-segment table. .*/28.transient volatileHashentry<k,v>[] table; 29. 30./*** The load factor for the hash table.          Even though this value 32.          * is same for all segments, it's replicated to avoid needing 33. * links to outer object. . *@serial.*/36.Final floatLoadfactor; 37.}

Count is used to count the number of data in this segment, which is volatile, which is used to coordinate modification and read operations to ensure that read operations are able to read almost the latest modifications. The coordination method is this: each modification operation made a structural change, such as adding/removing nodes (Modify the value of the node is not a structural change), write the Count value, read the value of count before each read operation

  

  

2.Java Set-concurrenthashmap realization principle and Source code analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.