解决CAS的ABA问题
AtomicStampedReference
一个值reference和时间戳stamp组成一个pair,每次cas的时候是cas一个pair
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
}
//比较设置 参数依次为:期望值 写入新值 期望时间戳 新时间戳
public boolean compareAndSet(V expectedReference, V newReference,
int expectedStamp, int newStamp)
@Test
public void Atomic() {
AtomicStampedReference asf = new AtomicStampedReference(10,0);
System.out.println("本次refernce:"+asf.getReference()+",本次stamp:"+asf.getStamp());
asf.compareAndSet(10, 11, 0, asf.getStamp()+1);
System.out.println("本次refernce:"+asf.getReference()+",本次stamp:"+asf.getStamp());
asf.compareAndSet(11, 10, asf.getStamp(), asf.getStamp()+1);
System.out.println("本次refernce:"+asf.getReference()+",本次stamp:"+asf.getStamp());
asf.compareAndSet(10, 11, 0, asf.getStamp()+1);
System.out.println("本次refernce:"+asf.getReference()+",本次stamp:"+asf.getStamp());
}
本次refernce:10,本次stamp:0
本次refernce:11,本次stamp:1
本次refernce:10,本次stamp:2
本次refernce:10,本次stamp:2
AtomicMarkableReference
一个pair是一个reference和一个mark,这个mark标志有没有修改过
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
AtomicMarkableReference asf = new AtomicMarkableReference(10,false);
System.out.println("本次refernce:"+asf.getReference()+",本次Mark:"+asf.isMarked());
asf.compareAndSet(10, 11, false, true);
System.out.println("本次refernce:"+asf.getReference()+",本次Mark:"+asf.isMarked());
asf.compareAndSet(11, 10, false, true);
System.out.println("本次refernce:"+asf.getReference()+",本次Mark:"+asf.isMarked());
//要修改的时候如果要求是未修改的,那么只有一个能改成功
本次refernce:10,本次Mark:false
本次refernce:11,本次Mark:true
本次refernce:11,本次Mark:true
哪些地方用到了CAS
原子类、锁
JUC.atomic
JUC.lock