CAS会导致ABA问题
CAS算法实现一个重要的前提是需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差内会导致数据的变化.
比如说一个线程one从内存位置V中取出A,线程Two也执行,将A–>B–>A,这时one进行CAS操作发现内存仍是A,然后one操作成功.这会造成很大的隐患,那么我们可以通过以下方法,在发生ABA问题后,不让数据修改
public class Study {
static AtomicStampedReference atomicStampedReference = new AtomicStampedReference(100,1);
public static void main(String[] args) {
//线程A实现ABA
new Thread(()->{
int stampe = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName()+" 默认版本号 "+stampe);
//
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicStampedReference.compareAndSet(100,101,stampe,stampe+1);
System.out.println(Thread.currentThread().getName()+"第一次修改后的版本号"+atomicStampedReference.getStamp());
atomicStampedReference.compareAndSet(101,100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
System.out.println(Thread.currentThread().getName()+"第二次修改后的版本号"+atomicStampedReference.getStamp());
},"A").start();
//线程B由于版本号不对等,修改失败
new Thread(()->{
int stampe = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName()+" 默认版本号 "+stampe);
//暂停3秒 让上个线程实现ABA
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean result = atomicStampedReference.compareAndSet(100,2018006727,stampe,stampe+1);
System.out.println(Thread.currentThread().getName()+"是否修改成功"+result+"\t"+atomicStampedReference.getStamp());
},"B").start();
}
}