Talk about high concurrency (12) analyzing java.util.concurrent.atomic.AtomicStampedReference source to see how to solve the ABA problem of CAs

Source: Internet
Author: User

Talking about high concurrency (11) Implementation of several spin locks (v) The java.util.concurrent.atomic.AtomicStampedReference atom variable is used to point to the end of the work queue, why use the atomicstampedreference atom variable instead of using atomicreference because This implementation is waiting for the same node in the queue to have a different state, and the same node will enter and exit the work queue multiple times, there may be ABA problems.


Students familiar with concurrent programming should know that there is an ABA problem in CAS operations. Let's look at the CAS operation first.

CAS (Compare and Swap) compare and swap operations are a ternary operation: The value of the destination address, T (arget), the expected E (xpected), the actual value R (EAL),

1. The target value T is set to the actual value R if the target value t = = expectation E, otherwise the target value is not changed

2. Regardless of whether the target value has changed, return the previous target value T


Logic similar to the following:

Package Com.zc.lock;public class CAS {private int value;public synchronized int get () {return value;} public synchronized int Compareandswap (int expected, int real) {int oldValue = value;if (value = = expected) {value = real;} return oldValue;} Public synchronized Boolean compareandset (int expected, int real) {return (expected = = Compareandswap (expected, real));}}

CAS only compares the expected and target values fairly, setting the new value fairly. So the ABA problem is here:

1. The CAs operation succeeds because CAs are only value comparisons, such as the target is a and the expected value is a. But at this point, the target a may not be the original A, it may be a becomes B, and then it becomes a. So called ABA problem, very image. The ABA problem may cause a program error, such as a node in a limited-time bounded queue lock has several states, although the reference value is a, but the state of the object may have changed, when a is not the original A.

2. It is important to note that the ABA problem is not that the CAS operation process a becomes a aba,cas operation is atomic and will not be interrupted . The ABA problem scenario is as follows:

First gets the value of a, and then the CAS (A, R), when the state of a in CAs actually points to the status of the object and it has been sent a change in the state it just acquired.


</pre><pre name= "code" class= "java" >a a = Ref.get ();//Do some operations according to the state of A//do something//CAS, this time there will be ABA problems, A pointed object may have changed Ref.compareandset (A, B)

The solution to the ABA problem is to set a timestamp for the state, which is a common practice of optimistic locking in concurrency, if the time stamp of the state has changed to prove that it is not the original object, so the operation failed

Timestamp with int atomicstampedreference<qnode> tail = new atomicstampedreference<compositelock.qnode> (NULL, 0) ; int[] Currentstamp = new int[1];//Currentstamp returns timestamp information Qnode Tailnode = Tail.get (Currentstamp); Tail.compareandset ( Tailnode, NULL, currentstamp[0], currentstamp[0] + 1)

Let's take a look at how Java.util.concurrent.atomic.AtomicStampedReference's source code is implemented.

The following code comes from JDK1.7, and is well-organized, with several key points to achieve:

1. Create a pair class to record the object reference and timestamp information, using int as the timestamp, the actual use of time stamp information to be made self-increment, otherwise the timestamp if repeated, there will be ABA problems. This pair object is an immutable object, all properties are final, and the of method returns a new immutable object every time

2. Use a reference to a volatile type to point to the current pair object, and the change is visible to all threads once the volatile reference has changed

3. When setting a method, create a new immutable pair object when the object you want to set is not the same as the current pair object

4. The Compareandset method creates a new pair object only if the reference and version number of the expected object and the reference and version of the target object are the same, and then uses the new pair object and the principle pair object to do the CAS operation

5. The actual CAS operation compares the current pair object with the new pair object, and the pair object encapsulates the reference and timestamp information


     private Static class Pair<t> {final T reference;        final int stamp;            Private Pair (T reference, int stamp) {this.reference = reference;        This.stamp = stamp; } static <T> pair<t> of (T reference, int stamp) {return new pair<t> (reference, stamp)        ;        }} private volatile pair<v> Pair;    Public Atomicstampedreference (V initialref, int initialstamp) {pair = Pair.of (Initialref, Initialstamp); } public void Set (V newreference, int. newstamp) {        pair<v> current = Pai r;        if (newreference! = Current.reference | | Newstamp! = current.stamp)              This.pair = Pair.of (newreference, Newstamp);    } public boolean compareandset (v   expectedreference,                                   v   newreference,                                   int expectedstamp,                                   int newstamp) {        pair<v> current = Pair;         return             Expectedreference = = Current.reference &&             Expectedstamp = = Current.stamp &&             ((nEwreference = = Current.reference &&               Newstamp = = Current.stamp) | |              Caspair (Current, Pair.of (Newreference, Newstamp)));   } private static final Sun.misc.Unsafe Unsafe = Sun.misc.Unsafe.getUnsafe ();  &nbsp ;  private static final long Pairoffset =        objectfieldoffset (UNSAFE, " Pair ", Atomicstampedreference.class);    private Boolean Caspair (pair<v> cmp, pair<v> val) {        return Unsafe.compareandswapobject (this, Pairoffset, CMP, Val);    }








Talk about high concurrency (12) analyzing java.util.concurrent.atomic.AtomicStampedReference source to see how to solve the ABA problem of CAs

Related Article

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.