$ java -cp target/classes com.ankurm.atomics.AbaProblemDemo === Part 1: a real ABA race against TreiberStack === Initial stack (top first): [A, B, C] Main thread popped, legitimately: "A", then "B" Stack after those two real pops: [C] Main thread pushed the SAME "A" node object back: [A, C] Thread 1's stale CAS result: CAS succeeded, pop() would have returned "A" Stack contents after Thread 1's stale CAS: [B, C] "B" is back in the stack even though the main thread already popped it and nobody ever pushed it again - Thread 1's CAS matched on reference identity alone (top was "A" both times it looked) and blindly installed a newTop ("B") that was computed from a read that happened before two pops and a push it never saw. "A" was also just handed out twice: once to the main thread's first pop(), once to Thread 1's stale one. === Part 2: AtomicStampedReference detects the same shape of race === Reader captured: ref="A", stamp=0 After a concurrent A -> B -> A round trip: ref="A", stamp=2 (reference is back to "A", but the stamp moved on) A plain AtomicReference.compareAndSet("A", "Z") would see reference == "A" and succeed: true AtomicStampedReference.compareAndSet("A", "Z", 0, 1) actually succeeded: false (false is correct - the stamp proves a change happened in between, even though the reference alone looks unchanged)