请稍等 ...
×

采纳答案成功!

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

关于public final int getAndAddInt(Object var1, long var2, int var4) 方法的一个问题

  • var5 = this.getIntVolatile(var1, var2); 从主内存中取出了共享变量count的最新值到当前线程的本地变量var5中;
  • 那么在var5 = this.getIntVolatile(var1, var2); 和 this.compareAndSwapInt(var1, var2, var5, var5 + var4)之间别的线程也会更新主内存中的count,导致var5和主内存中的count不一致,var5岂不是不能保证就是最新的主内存中count的副本吗?
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;
}

正在回答

2回答

你好,var5只能保证取出的是当时内存里最新的值,不保证之后调用compareAndSwapInt

时依旧和内存里的值仍然一致。本身取出var5最新值后去调用compareAndSwapInt也不一定直接成功,就因为这两个操作本身不具备原子性。但这并不影响 getAndAddInt 整个方法要完成的事情,这个原因在于:


首先,compareAndSwapInt 这个native方法涉及到的”检查相等则更新,否则不更新“这两个操作是原子性的,cpu指令来保证。


其次,getIntVolatile 和 compareAndSwapInt 这两个操作中间确实可能有其他操作,也就是var5刚从内存取了一次,内存里的值就更新了。但是他不是只做一次的。compareAndSwapInt会去检查当前线程里获取的值和内存里最新的值是否相等,只要不等就继续重新获取var5的最新值并重试这个过程,直到相等才进行更新。


实际中,getIntVolatile和compareAndSwapInt 两个操作中间尽管会插入其他操作,但要重试好几次的概率其实很小,这里不需要纠结一直会重试下去的可能,这里只能说理论上有可能会重试很多次,实际会很快退出重试的。


0 回复 有任何疑惑可以回复我~
  • 提问者 磊磊要酷酷滴 #1
    这次是真的扫除了我理解上的误区了,var5不是和var1比,而是和内存中的最新值比,扫清了这个误区,就豁然开朗了。谢谢老师的耐心解答^_^
    回复 有任何疑惑可以回复我~ 2019-03-29 14:54:41
Turren 2019-03-27 14:42:57
0 回复 有任何疑惑可以回复我~
  • 提问者 磊磊要酷酷滴 #1
    老师的回答和那位同学的回答都没能回答清楚;var5到底是不是主内存中的count在线程中的私有拷贝?如果是的话,私有拷贝当然可能落后于主内存中的count,而且这个落后的动作当然可以发生在两行代码之间,就是while循环的条件那一行。
    回复 有任何疑惑可以回复我~ 2019-03-27 18:54:58
  • Jimin 回复 提问者 磊磊要酷酷滴 #2
    每个人的理解多少都有些差异,因此一份回答不一定能满足所有人,你可以看看我针对你这个提问点的回答,是否能解答你的疑问,之前很多人是纠结compareAndSwapInt的原子性,因为这个方法有问题。
    回复 有任何疑惑可以回复我~ 2019-03-27 23:43:42
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信