请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于ABA问题

线程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回答

Jimin 2018-07-20 10:34:09

你好,你这问题到是很有意思,我挨个说一下。

先说第一个问题,你这里提到的“为什么又要改回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里传入的变量,继续尝试。如果不成功,则继续取出最新的值去处理,直到成功为止。

1 回复 有任何疑惑可以回复我~
  • 提问者 blanc_ #1
    谢谢老师 ,我又看了一遍重新仔细的想了想,理解通了!
    回复 有任何疑惑可以回复我~ 2018-07-20 17:51:19
  • zhusx 回复 提问者 blanc_ #2
    你好,在你的第二个问题上,我和你在有一样的疑问,看了老师的解答还是没想通,能解释下你是怎么想通的吗。
    回复 有任何疑惑可以回复我~ 2018-08-28 21:37:43
  • kimvra 回复 zhusx #3
    我的理解是,在执行compareandswap的时候,还会用var1和var2去取到实际的底层的值,也就是这个时候取到的值才是最新最新的,所以用最新的值和之前取到的var5作比较能判断是否被其他线程修改过。
    回复 有任何疑惑可以回复我~ 2019-01-16 22:04:06
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信