Detailed explanation of the new atomic operation class longadder in jdk8
preface
This article mainly introduces the related contents of the new atomic operation class longadder in jdk8 for your reference and learning. Let's take a look at the detailed introduction together
Longadder brief introduction
Longadder, similar to atomiclong, is an atomic increasing or decreasing class. Atomiclong has provided non blocking atomic operations through CAS. Compared with the synchronizer using blocking algorithm, its performance is very good, but the JDK development team is not satisfied because atomiclong's performance is unacceptable under very high concurrent requests, Although atomiclong uses CAS, it continues to try through infinite loop spin lock after CAS failure
Under high concurrency, N multiple threads operating on a variable at the same time will cause a large number of threads to fail and then be in the spin state, which greatly wastes CPU resources and reduces concurrency. Since atomiclong's performance is reduced due to too many threads competing for the update of a variable at the same time, if a variable is decomposed into multiple variables and the same number of threads compete for multiple resources, won't the performance problem be solved? Yes, this is the idea of the longadder provided by jdk8. The difference between the two is indicated by graphics below.
As shown in the figure, atomiclong is that multiple threads compete for the same variable at the same time.
As shown in the figure, longadder internally maintains multiple variables, and each variable is initialized to 0. Under the condition of the same concurrency, the number of threads competing for a single variable will be reduced, which is a disguised reduction in the concurrency of competing for shared resources. In addition, if multiple threads fail to compete for the same atomic variable, it is not a spin CAS retry, but an attempt to obtain the locks of other atomic variables, Finally, when obtaining the current value, it is returned after accumulating the values of all variables.
Longadder maintains an atomic update array with delayed initialization and a base variable base The size of the array is kept to the nth power of 2. The subscript of the array table is represented by the mask of the hashcode value of each thread. The variable entity in the array is cell type. Cell type is an improvement of atomiclong to reduce cache contention. Byte filling is wasteful for most atomic operations, because atomic operations are carried out irregularly in memory, Multiple atomic operations are not in contact with each other, but atomic array elements stored adjacent to each other will often share cache rows, so this is an improvement in performance.
In addition, because cells occupy relatively large memory, they are not created at the beginning, but created when needed, that is, inert loading. When there is no space at the beginning, all updates are to operate the base variable,
The spin lock cellsbusy is used to initialize and expand the array table. There is no need to use a blocking lock here. Once the thread finds that the current subscript element fails to obtain the lock, it will try to obtain the lock of other elements in the following table. For a more detailed description, please look forward to the publication of the book "Fundamentals of Java Concurrent Programming and source code analysis"
summary
The above is the whole content of this article. I hope the content of this article can bring some help to your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.