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