关于ABA问题
来源:3-2 线程安全性-原子性-atomic-2
![](http://img1.sycdn.imooc.com/user/54584f6100019caf02200220-100-100.jpg)
blanc_
2018-07-20
线程2将内存中的值A取出来变成了B,然后又改回成了A,没理解为什么线程2要做这种操作
比如内存中是2 ,线程B的工作内存中也是2,满足cas条件,所以B会把主存中的值修改为3,皆大欢喜,但是为什么又要改回2?
还有一个问题 假设线程1 做do操作时内存取出主存中的值var5=1 自己工作内存中的var2是也是var2 =1
但是在执行while(!thiscompareandswapint())之前 有另一个线程2 do取出的主存中的值var5 = 1 ,
自己工作内存中的var2 也是 var2 =1,所以满足cas并且他做了cas操作 , 再回来看线程1 他执行cas里的var5 还是do方法取出的1 ,所以也满足cas操作,但是时间上var5的值已经被线程2修改为2了,不懂这之中是什么道理 难道在cas操作中又从主存中取了一次var5么 ? 不然怎么保证一个线程do取var5 和 while这之间的时间一定是没问题的呢
1回答
-
你好,你这问题到是很有意思,我挨个说一下。
先说第一个问题,你这里提到的“为什么又要改回2”,其实这时候不是他要不要的问题,而是某些情况下导致当前数据和之前某次操作完之前相同,这时候如果不通过版本来管理,是有一定几率丢掉中间的操作,导致对最终的结果造成一定的影响。例子可以参考这篇文章里说的链表实现的堆栈问题:https://www.cnblogs.com/549294286/p/3766717.html
再来说第二个问题,我们先来看底层实现,
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}这里是个do...while循环,当compareAndSwapInt这个方法返回false时,代表实际的值和当前线程里的值已经不一样了,这时会重新取出var5这个变量,而且是通过getIntVolatile保证取到最新的值,这时修正compareAndSwapInt里传入的变量,继续尝试。如果不成功,则继续取出最新的值去处理,直到成功为止。
132019-01-16
相似问题