ABA问题的产生
package cn.chen.demo.referencedemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
public class ReferenceDemo {
//原子引用:初始化值为100
static AtomicReference<Integer> atomicReference = new AtomicReference<Integer>(100);
public static void main(String[] args) {
// T1线程:将初始值100更改为101,再将101改回100。这里其实主内存的共享变量已经发生过变化了
// T2线程:误以为当前的这个100就是初始值,因此对其进行了修改。
new Thread(()->{
atomicReference.compareAndSet(100, 101);
atomicReference.compareAndSet(101, 100);
}, "T1线程").start();
new Thread(()->{
//暂停1秒钟T2线程,保证T1线程完成了一次ABA操作
try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + ":"
+ atomicReference.compareAndSet(100, 1024) + "," + atomicReference.get());
}, "T2线程").start();
}
ABA问题的解决
package cn.chen.demo.referencedemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
public class ReferenceDemo {
//版本号原子引用:初始化变量为100,版本号为1
static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<Integer>(100, 1);
public static void main(String[] args) {
//通过加入版本号来控制
new Thread(()->{
int stamp = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName() + "的当前版本号为:"+ stamp);
//暂停1秒钟T3线程
try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); }
atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(), atomicStampedReference.getStamp()+1);
atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp()+1);
}, "T3线程").start();
new Thread(()->{
int stamp = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName() + "的当前版本号为:"+ stamp);
//暂停3秒钟T4线程,保证T3线程完成了一次ABA操作
try { TimeUnit.SECONDS.sleep(3); } catch (Exception e) { e.printStackTrace(); }
Boolean result = atomicStampedReference.compareAndSet(100, 1024, stamp, stamp+1);
System.out.println(Thread.currentThread().getName()+"修改:"+result);
System.out.println("当前版本号:"+atomicStampedReference.getStamp());
}, "T4线程").start();
}
}