In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
How to analyze ConcurrentHashMap, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.
Visibility of data
To get to the point, concurrentHashMap believes that a lot of people use it, because it is really easier to use than HashMap in terms of data security and better than hashtable in performance. It is well known that when a thread manipulates a variable, for example, a thread needs to go through two pieces of memory, the main memory and the working memory, when it executes. Well, when thread An adds 1 to I, it needs to go to the main memory to get the value of the variable. At this time, there is a copy of the variable data in the working memory. After executing these, the variable is really added 1. But thread B also has to operate on the variable at this time, and logically there is no restriction on maintaining multi-thread access. It is very likely that when thread A gets the data from the main memory and modifies it, thread B goes to the main memory to get the data, but at this time, the data of the main memory has not been updated, and the A thread has not had time to backfill the variable after adding 1 into the main memory. At this time, logic errors will occur in the case of the operation of the two threads.
Atomicity
Atomicity means that when a thread A modifies the value of I, thread B cannot do anything with I between taking out I and writing the new I value to I. That is, to ensure that the operation of a thread on I is atomic, so that dirty reading of the data can be avoided.
The role of volatile
Volatile ensures the visibility of data between multiple threads, and each thread goes back to the main memory to get the volatile-modified variables, so when thread A modifies the volatile-modified data, other threads must see the latest data after modification, and because the volatile-modified variable data has to go to the main memory every time, there will be some sacrifices in performance.
Measure
HashMap is not safe in multithreaded scenarios. Although hashtable locks on the data table, even though the data is secure, its performance is not as good as HashMap. So take a look at how concurrentHashMap solves these problems.
ConcurrentHashMap consists of multiple segment, each segment contains a hashtable of a HashEntry array, and each segment contains operations on its own hashtable, such as get,put,replace (these operations are the same as HashMap logic, except that concurrentHashMap adds a reentrant lock ReentrantLock when performing these operations), and locks its own hashtable when these operations occur. Since each segment write only locks its own hashtable, it is possible for multiple threads to write at the same time, which is certainly better than if there is only one hashtable lock. Popularly speaking, concurrentHashMap consists of multiple hashtable.
Source code
Take a look at the remove operation of concurrentHashMap
V remove (Object key, int hash, Object value) {lock (); / / reentrant lock try {int c = count-1; HashEntry [] tab = table; int index = hash & (tab.length-1); HashEntry first = tab [index]; HashEntry e = first While (e! = null & & (e.hash! = hash | |! key.equals (e.key)) e = e.nextV oldValue = null; if (e! = null) {V v = e.value If (value = = null | | value.equals (v)) {oldValue = v; / / All entries following removed node can stay / / in list, but all preceding ones need to be / / cloned. + + modCount; HashEntry newFirst = e.next; for (HashEntry p = first; p! = e; p = p.next) newFirst = new HashEntry (p.key, p.hash, newFirst, p.value) Tab [index] = newFirst; count = c; / / write-volatile}} return oldValue;} finally {unlock (); / / release lock}}
Count is modified by volatile to ensure the visibility of count and avoid logic errors when manipulating data. The remove operation in segment is roughly the same as HashMap, and HashMap has no lock () and unlock () operations.
Take a look at concurrentHashMap's get source code
V get (Object key, int hash) {if (count! = 0) {/ / read-volatile HashEntry e = getFirst (hash) / / if it is not found, return null while (e! = null) {if (e.hash = = hash & & key.equals (e.key)) {/ / because it is not locked, there may be updates during the get process, and the value corresponding to the key you get may be null You need to judge V v = e.value alone. / / if value is not null, return the obtained value if (v! = null) return v; return readValueUnderLock (e); / / recheck} e = e.next }} return null;}
The instructions on concurrentHashMap's get have been annotated in the above code, so I won't say much here.
Take a look at put in concurrentHashMap
Public V put (K key, V value) {if (value = = null) throw new NullPointerException (); int hash = hash (key.hashCode ()); return segmentFor (hash) .put (key, hash, value, false);}
You can see that concurrentHashMap does not allow key or value to be null
Next, let's take a look at segment's put.
V put (K key, int hash, V value, boolean onlyIfAbsent) {lock (); try {int c = count; if (C++ > threshold) / / ensure capacity rehash (); HashEntry [] tab = table; int index = hash & (tab.length-1) HashEntry first = tab [index]; HashEntry e = first; while (e! = null & & (e.hash! = hash | |! key.equals (e.key) e = e.next; V oldValue; if (e! = null) {oldValue = e.value If (! onlyIfAbsent) e.value = value;} else {oldValue = null; + + modCount; tab [index] = new HashEntry (key, hash, first, value); count = c / / write-volatile} return oldValue;} finally {unlock ();}}
Reentrant locks are also added, and the rest is basically the same as HashMap logic. What is worth mentioning is the putval added in jdk8, so I won't say much here.
ConcurrentHashmap divides the data structure into multiple Segment, and also uses reentrant locks to solve high concurrency. It is divided into multiple segment to reduce the strength of locks, adding locks when adding, not locking when indexing, and using volatile to modify count in order to maintain the visibility of count, which are common means of jdk to solve concurrency and multithreaded operations.
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.