ConcurrentHashMap is based on JDK1.8 source code analysis

foreword

Statement, this article uses jdk1.8

Review of previous chapters:

This article mainly explains ConCurrentHashMap ~

Before reading this article, it is best to have a little bit of data structure basics:

Of course, if there is something wrong, please bear with me and correct me in the comments~

1. Analysis of ConCurrentHashMap

Anyway, I didn't touch ConCurrentHashMap when I was a beginner. I don't know if you have touched it~

This class is rarely heard. It is a more complex class in the collection, and it involves some multi-threading knowledge points.

Don't be afraid if you don't know or forget the knowledge points of multi-threading. I will briefly introduce where the knowledge points of multi-threading are used, and give the corresponding information to read~

Alright, let's start~

1.1 First acquaintance with ConCurrentHashMap

The bottom layer of ConCurrentHashMap is: hash table + red-black tree , which is the same as HashMap.

 

 

From the previous chapters, we can also find that: to understand what a class does the fastest, we can just look at the top comment of the source code!

I simply translated the comments at the top (my English level is slag, please bear with me if there are any mistakes~ Welcome to correct me in the comment area)

 

 

Based on the comments above, we can briefly summarize:

  • The bottom layer of JDK1.8 is hash table + red-black tree
  • ConCurrentHashMap supports highly concurrent access and update, it is thread- safe
  • The retrieval operation does not need to be locked, and the get method is non-blocking
  • Both key and value are not allowed to be null

1.2 JDK1.7 underlying implementation

The above indicates that the bottom layer of JDK1.8 is: hash table + red-black tree, which means that the bottom layer of JDK1.7 is different from JDK1.8~

The bottom layer of JDK1.7 is: segment+HashEntry array:

 

 

Source: https://blog.csdn.net/panweiwei1994/article/details/78897275

  • Segment inherits ReentrantLock , and each segment has a lock, called " lock segment "

Just get to know it~

1.3 Why do you need ConCurrentHashMap with Hashtable

  • Hashtable adds Synchronized to each method to complete synchronization, which is inefficient.
  • ConcurrentHashMap achieves synchronization by partially locking and utilizing the CAS algorithm .

1.4 A brief introduction to CAS algorithm and volatile

Before looking at the source code of ConCurrentHashMap, let's briefly talk about the CAS algorithm and the volatile keyword

CAS (Compare and swap) is a well -known lock-free algorithm

CAS has 3 operands

  • memory value V
  • old expected value A
  • new value B to be modified

Modify memory value V to B if and only if expected value A and memory value V are the same, otherwise do nothing

  • When multiple threads try to use CAS to update the same variable at the same time, only one of them can update the value of the variable (when A and the memory value V are the same, change the memory value V to B) , and the other threads all fail, the failed thread Instead of being suspended , you are told to lose this race and can try again **(otherwise do nothing)**

After reading the above description, it should be easy to understand. First compare whether they are equal, and if they are equal, replace (CAS algorithm)

Next, let's take a look at the volatile keyword , which is rarely used in beginners. Anyway, I didn't use it, and I often see it when I look at Java-related interview questions. I think it is a very mysterious and difficult keyword. In fact, it is quite easy to understand~

Classic summary of volatile: volatile is only used to ensure the visibility of the variable to all threads, but does not guarantee atomicity

Let's break it down to explain:

  • Guarantee the visibility of the variable to all threads
    • In a multi-threaded environment: when this variable is modified, all threads will know that the variable has been modified , which is the so-called "visibility"
  • Atomicity is not guaranteed
    • Modifying a variable (assignment) is essentially a number of steps in the JVM , and within those steps (from loading the variable to modifying), it is not safe .

If you don't understand or want to understand its principles in depth, you can refer to the following blog posts:

1.5ConCurrentHashMap field

There are several domain objects:

 

 

Let's take a brief look at what they are:

 

 

After reading it for the first time, I don't quite know what some attributes do, but it may become clear after continuing to read ~

1.6ConCurrentHashMap constructor

There are 5 construction methods of ConcurrentHashMap:

 

 

The specific implementation is as follows:

 

 

It can be found that there are several calls in the constructor tableSizeFor(). Let's take a look at what he does:

After clicking in, I found that, ah, so I have seen this method, when HashMap...

 

 

It is used to get the number greater than the parameter and the nearest integer power of 2 ...

Assigning it to the sizeCtl attribute also shows: this is the size of the next expansion ~

1.7put method

Finally came to one of the most core methods: put method~~~~~

Let's first take a look at what the put method does as a whole:

 

 

Next, let's see what happens when the hash table is initialized:initTable()

 

 

  • Only have one thread initialize the hash table !

1.8 get method

From the top comment we can read that the get method is lock -free and non-blocking.

We can find that the Node node is rewritten, and the volatile keyword modification is set, so that it gets the latest value every time.

 

 

 

 

2. Summary

The core knowledge of ConcurrentHashMap is briefly introduced above, and there are many knowledge points that have not been mentioned, and the author's level cannot understand it~~ Students who are interested in entering can go to the following link to continue learning.

Let me briefly summarize the core points of ConcurrentHashMap:

  • The underlying structure is a hash table (array + linked list) + red-black tree , which is the same as HashMap.
  • Hashtable synchronizes all methods, which is inefficient. As a highly concurrent container, ConcurrentHashMap achieves thread safety through partial locking + CAS algorithm . CAS algorithm can also be considered as a kind of optimistic locking ~
  • In a high concurrency environment, statistics (calculating size... etc.) are actually meaningless, because the size value changes at the next moment.
  • The get method is non-blocking and lock-free. Rewrite the Node class and modify the next by volatile to achieve the latest set value every time
  • Neither key nor Value of ConcurrentHashMap can be null

References:

If there is no accident tomorrow, I may write a set collection, so stay tuned ~~~~

Article directory navigation : zhongfucheng.bitcron.com/post/shou-j…

If there are any mistakes in the article, please correct me, and we can communicate with each other. Students who are used to reading technical articles on WeChat and want to get more Java resources can follow WeChat public account: Java3y . For everyone's convenience, I just created a new QQ group: 742919422 , you can also go to communicate. Thank you for your support! Hope to introduce more to other friends in need


 

Guess you like

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