ABA本质是并发情况下使用cas修改数据,在都成功的情况下丢失一次修该信息,比如 A-C-D,A-B-C
ABA是否对程序造成影响是否需要解决?
1.如果只是单纯的数值数据,无业务关联逻辑,没有影响,比如Lock锁的实现就不考虑这个问题,因此如果只是单纯的技术或者统计请忽略aba问题
2.如果数据是有业务含义的就需要处理,尤其是资金问题
java里面的解决办法
1.操作同一个对象的时候,每次都通过new新对象进行包装(其实变相避免了两个A的出现),如下
public class ConcurrentStack {
AtomicReference<Node> top = new AtomicReference<Node>();
public void push(String item){
Node newTop = new Node(item);
Node oldTop;
do{
oldTop = top.get();
newTop.next = oldTop;
}
while(!top.compareAndSet(oldTop, newTop));
}
public String pop(){
Node newTop;
Node oldTop;
do{
oldTop = top.get();
if(oldTop == null){
return null;
}
newTop = oldTop.next;
}
while(!top.compareAndSet(oldTop, newTop));
return oldTop.item;
}
}
2.常规办法 使用 AtomicStampedReference 或者 AtomicMarkableReference
AtomicStampedReference可以知道,引用变量中途被更改了几次。有时候,我们并不关心引用变量更改了几次,只是单纯的关心是否更改过,所以就有了AtomicMarkableReference。AtomicMarkableReference的唯一区别就是不再用int标识引用,而是使用boolean变量——表示引用变量是否被更改过。构造函数
private static AtomicStampedReference atomicStampedRef = new AtomicStampedReference(100, 0);
atomicStampedRef.compareAndSet(100, 101, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1);