Hesey uses a very expressive example in his question “Solving ABA Problems with Atomic stampede ference”.
-
There is a stack (single linked list implementation) as follows:
a.next = b, b.next = null
The top element of the stack is A, and now Thread1 is ready to change the top element of the stack to B, while Thread2 does the following, pushing A and B off the stack and pushing A, C and D onto the stack
The thread finds that the top of the stack is A (but now A is not the original A), and Thread1 changes the top element of the stack to B, where the structure is
C and D are missing, and only element B is in the stack
How to solve it?
Next = D3, a5. next = C4 thread 1 working, A5! = A1, update failed.
Code sample
The following code illustrates the 1 result of AtomicInteger and AtomicStampedReference, respectively.
class Test{
private static AtomicInteger atomicInt = new AtomicInteger(100);
private static AtomicStampedReference atomicStampedRef = new AtomicStampedReference(100.0);
public static void main(String[] args) throws InterruptedException {
Thread intT1 = new Thread(new Runnable() {
@Override
public void run(a) {
atomicInt.compareAndSet(100.101);
atomicInt.compareAndSet(101.100); }}); Thread intT2 =new Thread(new Runnable() {
@Override
public void run(a) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
boolean c3 = atomicInt.compareAndSet(100.101);
System.out.println(c3); // true
System.out.println(atomicInt); / / 101}}); intT1.start(); intT2.start(); intT1.join(); intT2.join(); System.out.println("= = = = = = = = = = = = = =");
Thread refT1 = new Thread(new Runnable() {
@Override
public void run(a){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("* * * *");
}
atomicStampedRef.compareAndSet(100.101, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1);
atomicStampedRef.compareAndSet(101.100, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1);
};
});
Thread refT2 = new Thread(new Runnable() {
@Override
public void run(a) {
int stamp = atomicStampedRef.getStamp();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
}
boolean c3 = atomicStampedRef.compareAndSet(100.101, stamp, stamp + 1);
System.out.println(c3); // false
System.out.println(atomicStampedRef.getReference()); // 100, CAS failed}}); refT1.start(); refT2.start(); refT1.join(); refT2.join(); }}Copy the code