AtomicInteger source code analysis, atomicinteger source code

Source: Internet
Author: User

AtomicInteger source code analysis, atomicinteger source code

  • Problem background

  Recently, I 've seen the use of AtomicInteger to modify the count in the queue blockingqueue. I 've also seen some explanations of AtomicInteger, and I have learned a lot about its implementation methods.

  • Basic Introduction

To have a deep understanding of AtomicInteger, you must understand the pessimistic and optimistic locks. Cpu is time-division multiplexing, that is, the cpu time slice is allocated to different threads/processes for execution in turn. cpu switching is required between the time slice and the time slice, that is, the process will be switched. Switching involves clearing registers and caching data. Then, reload the data required by the new thread. When a thread is suspended, it is added to the blocking queue. at a certain time or condition, it is woken up through Y () and notifyAll. When a resource is unavailable, the cpu is transferred out and the current waiting thread is switched to the blocking status. When the resource (such as a shared data) is available, the thread will be awakened to enter the runnable status and wait for cpu scheduling. This is the implementation of a typical pessimistic lock. An exclusive lock is a pessimistic lock, and synchronized is an exclusive lock. It assumes the worst case and is executed only when other threads do not interfere, all other threads that need to be locked will be suspended, waiting for the threads holding the lock to release the lock.

However, there is a large overhead in process suspension and recovery execution. When a thread is waiting for a lock, it cannot do anything, so pessimistic locks have great disadvantages. For example, if a thread requires a certain resource, but the resource takes up a short time, when the thread first grabs the resource, the resource may be occupied. If the thread is suspended at this time, the resource may be immediately available, and it takes a long time to re-seize the lock, the time cost will be very high.

So there is an optimistic lock concept. His core idea is to complete an operation without locking each time, assuming that there is no conflict. If the conflict fails, retry until the operation is successful. In the preceding example, a thread can keep a while loop instead of giving up the cpu. If the thread fails, retry until it is successful. Therefore, when the data competition is not serious, Optimistic Locking is better. For example, the bottom-layer synchronization of CAS with AtomicInteger is an application of Optimistic Locking.

CAS means Compare and Swap. Many CPUs directly support CAS commands. CAS is an optimistic locking technique. When multiple threads attempt to use CAS to update the same variable at the same time, only one thread can update the value of the variable, while other threads fail, the failed thread will not be suspended, but will be told that the competition failed and can be tried again. CAS has three operands, memory value V, Expected Value A, and new value B to be modified. If and only when the expected value A is the same as the memory value V, change the memory value V to B. Otherwise, nothing is done.

ABA problems may occur during CAS operations. That is, if the value of V changes from A to B and then from B to A, it is still considered A change and the steps in the algorithm need to be re-executed. There is A simple solution: not to update A reference value, but to update two values, including A reference and A version number, even if the value is changed from A to B and then to, the version number is also different.

  • AtomicInteger Analysis

Understanding of classes in the Atomic package:

The Atomic package is another Java package specifically designed for thread security under Java. util. concurrent. It contains multiple Atomic operation classes. This package provides a group of atomic variable classes. Its basic feature is that in a multi-threaded environment, when multiple threads simultaneously execute the methods contained by these class instances, they are exclusive, that is, when a thread enters the method, when the command is executed, it will not be interrupted by other threads, and other threads will wait until the execution of this method is complete, just like the spin lock, the JVM selects another thread from the waiting queue. This is just a logical understanding. It is actually implemented by using hardware-related commands and does not block threads (or just blocks threads at the hardware level ). You can operate on basic data, basic data in the array, and basic data in the class. The atomic variable class is equivalent to a generalized volatile variable that supports atomic and conditional read-Modify-write operations. -- Reference @Chenzehe.

Let's take a look at the implementation of the getAndIncrement () method in AtomicInteger:

1 public final int getAndIncrement() {2         for (;;) {3             int current = get();4             int next = current + 1;5             if (compareAndSet(current, next))6                 return current;7         }8 }

This method first obtains the current value attribute value, adds value to 1, and assigns a value to a local next variable. However, these two steps are not thread-safe, however, there is an internal endless loop, constantly performing the compareAndSet operation until the operation is successful, that is, the modification is basically in the compareAndSet method. The code of the compareAndSet () method is as follows:

1 public final boolean compareAndSet(int expect, int update) {2         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);3 }

CompareAndSet is the value attribute value obtained when the method is executed, next is the value after 1 is added, and compareAndSet is used to call Sun's UnSafe compareAndSwapInt method. This method is the native method, compareAndSwapInt is implemented based on the CAS command of the CPU. Therefore, CAS-based operations can be considered as non-blocking. failure or suspension of a thread will not cause other threads to also fail or stop. The CAS operation is the CPU primitive, so the performance is better.

The following is an example of how to implement AtomicInteger:

Counter (Counter), using the convenient lock mechanism synchronized keyword in Java, the initial code is as follows:

 1 public class Counter { 2     private int value;   3        4     public synchronized int getValue() {   5         return value;   6     }   7    8     public synchronized int increment() {   9         return ++value;  10     }  11   12     public synchronized int decrement() {  13         return --value;  14     }  15 }

The synchronized keyword is based on the blocking lock mechanism. That is to say, when a thread has a lock, other threads accessing the same resource need to wait until the thread releases the lock, this is also the pessimistic lock we mentioned earlier. There will be some problems: first, what if the priority of the blocked thread is very high? What should I do if the thread that obtains the lock never releases the lock? (This is very bad ). In another case, if there are a large number of threads competing for resources, the CPU will spend a lot of time and resources to deal with these competitions (in fact, the main work of the CPU is not). At the same time, there may also be some situations such as deadlocks. In the end, the lock mechanism is actually a rough and granular mechanism, which is a little too heavy than the demand for counters. Therefore, we look forward to a more appropriate and efficient thread security mechanism for this requirement.

The following example illustrates how to simulate the CAS mechanism to implement Counter:

CAS class:

 1 public class SimpleCAS { 2     private volatile int value; 3     public synchronized int getValue(){ 4         return value;   5     }  6     public synchronized boolean comperaAndSwap(int expectedValue,int newValue){ 7         int oldValue = value; 8         if(oldValue == expectedValue){ 9             value = newValue;10             return true;11         }else{12             return false;13         }14     }15 }

CASCounter class:

 1 public class CASCounter { 2     private SimpleCAS cas;   3     public int getValue(){ 4         return cas.getValue(); 5     } 6     public int increment(){ 7         int olevalue = cas.getValue(); 8         for (; ;) { 9             if(cas.comperaAndSwap(olevalue, olevalue+1)){10                 return cas.getValue();11             }12         }13          14     }15 }

The above simulation is not the true implementation of CSA. In fact, we did not perform any synchronization operations at the language level. You can also see that the source code has no lock applied to it, but why is it thread-safe? This is the mystery of these classes under the Atomic package: the language layer does not handle it. We will hand it over to the hardware-CPU and memory, and use the multi-processing capability of the CPU to implement hardware-level blocking, coupled with the volatile variable feature, thread security based on atomic operations can be achieved. Therefore, CAS is not non-blocking, but blocking is not in terms of language and thread, but in terms of hardware. Therefore, such operations will undoubtedly be faster and more efficient!

To sum up, AtomicInteger is an optimistic concurrency policy based on conflict detection. As you can imagine, this optimism increases exponentially when the number of threads is very large.

Reference: http://blog.csdn.net/zhangerqing/article/details/43057799,http://www.mamicode.com/info-detail-862009.html

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.