Atomicinteger Source Analysis--optimistic lock implementation based on CAs

Source: Internet
Author: User

Atomicinteger Source Analysis--optimistic lock implementation based on CAS1. Pessimistic lock and optimistic lock

We all know that the CPU is time-division multiplexing, that is, the CPU is allocated to different thread/process in turn, time slices and time slices between the need for CPU switchover, that is, the process of switching. Switching involves emptying registers and caching data. Then reload the required data for the new thread. When a thread is suspended, it is added to the blocking queue, and at a certain time or condition, it wakes up by notify (), Notifyall (). When a resource is unavailable, the CPU is conceded, and the current waiting thread is switched to a blocking state. When a resource (such as a shared data) is available, wake the thread and let him enter the runnable state to wait for the CPU to dispatch. This is the implementation of a typical pessimistic lock. An exclusive lock is a pessimistic lock, synchronized is an exclusive lock that assumes a worst case scenario and only executes if the other thread is not causing interference, causing all other threads that need to be locked to hang, waiting for the thread that holds the lock to release the lock.

However, there is a significant overhead in the process of suspending and resuming execution. When a thread is waiting for a lock, it cannot do anything, so pessimistic locking has great drawbacks. For example, if a thread needs a resource, but this resource occupies a short time, when the thread first preempted the resource, it might be occupied, and if this thread is suspended at this point, it may be immediately discovered that the resource is available, and then it takes a long time to re-preempt the lock, and the time cost will be very high.

So there is the concept of optimistic locking, his core idea is that each time without locking but assume that there is no conflict to complete an operation, if the conflict failed to retry, until successful. In the example above, a thread can not give up the CPU, but it always loops, and if it fails, retry until it succeeds. Therefore, optimistic locking works better when data contention is not severe. CAs, for example, is an application of optimistic locking ideas.

2. Implementation of CAs in Java

CAS is the meaning of compare and swap, compared and manipulated. Many CPUs directly support CAS directives. CAS is an optimistic locking technique that when multiple threads try to update the same variable simultaneously using CAS, only one of the threads can update the value of the variable, and the other threads fail, and the failed thread is not suspended, but is told that the competition has failed and can try again. CAS has 3 operands, a memory value of V, an old expected value of a, and a new value to be modified B. If and only if the expected value A and the memory value of the V phase, the memory value of V is modified to B, otherwise do nothing.

The underlying support is introduced in JDK1.5, which exposes CAS operations on types such as int, long, and object references, and the JVM compiles them into the most efficient method provided by the underlying hardware, and compiles them into corresponding machine instructions on the platform running CAs. All of the atomic variable types under the Java.util.concurrent.atomic package, such as Atomicinteger, use these underlying JVM support to provide an efficient CAS operation for reference types of numeric types.

In CAS operations, ABA problems occur. Is that if the value of V is changed from a to B and then B to a, then it is still considered to have changed and the steps in the algorithm need to be re-executed. There is a simple solution: instead of updating the value of a reference, update two values, including a reference and a version number, even if the value changes from A to B, and then to a, the version number is different. Atomicstampedreference and atomicmarkablereference Support performing atomic conditional updates on two variables. Atomicstampedreference updates an "object-reference" two tuple, which avoids the ABA problem by adding "version number" to the reference, and Atomicmarkablereference updates an "object reference-Boolean" two-tuple.

3. Implementation of the Atomicinteger.

Atomicinteger is an Integer class that supports atomic operations, which is to ensure that the increment and decrease of the Atomicinteger type variable is atomic, and there is no data inconsistency problem with multiple threads. If you do not use Atomicinteger, to implement an ID that is obtained sequentially, you must lock the operation on each fetch to avoid the phenomenon of getting the same ID when concurrency occurs.

The next step in the source code is to see how Atomicinteger is implemented in atomic operations.

First look at the Incrementandget () method, the following is the specific code.

Public final int Incrementandget () {for        (;;) {            int current = Get ();            int next = current + 1;            if (Compareandset (current, next))                return next;        }    }


Through the source code, you can know that this method is to get to the current Value property values, and then add value 1, assigned to a local next variable, however, these two steps are non-thread-safe, but there is a dead loop inside, continue to do compareandset operation, Until successful, that is, the modification of the root in the Compareandset method, the code of the Compareandset () method is as follows:

Public final Boolean compareandset (int expect, int. update) {        return unsafe.compareandswapint (this, Valueoffset, expect, update);    }


The declaration of the Compareandswapint () method of the Compareandset () method call is a native method.

Publicfinal Native Boolean compareandswapint (Object var1, long var2, int var4, INTVAR5);

Compareandset The value that is obtained when the method is executed, next is the value after 1, and Compareandset does the compareandswapint to call Sun's UnSafe method to complete, this method is the native method, Compareandswapint is based on the CPU of the CAS directive to achieve. So CAS-based operations can be considered non-blocking, and failure or suspension of one thread will not cause other threads to fail or hang. And because CAS operations are CPU primitives, performance is better.

Similarly, there is the Decrementandget () method. It differs from Incrementandget () by the value minus 1, which is assigned to the next variable.

Atomicinteger also have the getandincrement () and Getanddecrement () methods, their implementation principle and the above two methods exactly the same, the difference is the return value is different, the first two methods return is the value after the change, that is, next. The two methods return the value before the change, that is, current. There are a lot of other ways to do it.

Atomicinteger Source Analysis--optimistic lock implementation based on CAs

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.