请稍等 ...
×

采纳答案成功!

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

AtomicInteger


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;
}

public final int incrementAndGet() {
   return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

假设var1为count,var2为count的当前的值为2,var4应当为1

如果getAndAddInt执行成功了,那么将会返回var5的值同时var5应当为3

那么在incrementAndGet方法中最后返回的结果将是4.但是传进来的count的值为2这样不就多加了1吗

正在回答 回答被采纳积分+3

1回答

Jimin 2018-08-29 23:36:51

你好,这里的compareAndSwapInt(var1, var2, var5, var5 + var4)换成 compareAndSwapInt(obj, offset, expect, update)能清楚一些,如果obj内的value和expect相等,就证明没有其他线程改变过这个变量,那么就更新它为update,否则只是返回false。这个理解时一定要结合他所在的那个函数:

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;
}

我们来看这一段,本质上 compareAndSwapInt (obj, offset, expect, update)这个方法是个cpu指令级的操作,能保证原子性。但是他不一定能执行成功,一旦执行不成功,则通过 var5 = this.getIntVolatile(var1, var2)  取出主存里当前最新的值,然后更新这里的expect(这时update在传入compareAndSwapInt时也会跟着更新),继续执行compareAndSwapInt (obj, offset, expect, update)操作。这样通过无锁自旋的方式不断尝试不断更新直至成功,同时来保证线程安全性,并且跳出当前的循环。在线程竞争不激烈时,可以很快的返回。

0 回复 有任何疑惑可以回复我~
  • 提问者 慕码人1088981 #1
    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;
    }
    这段保证了只有obj中的value与主内存中的一样才会进行某些操作,但是如果现在obj中的value受到其他线程的影响导致与主内存中的值不一致,那么不论怎么循环只要不改变obj或主内存中的值也都无法达到使obj中的value与主内存的值相同的结果啊?
    回复 有任何疑惑可以回复我~ 2018-08-30 13:43:46
  • Jimin 回复 提问者 慕码人1088981 #2
    getIntVolatile那个方法会取出主存里最新的值,重新尝试,直到成功
    回复 有任何疑惑可以回复我~ 2018-08-30 14:56:38
  • 提问者 慕码人1088981 回复 Jimin #3
    假设当前的obj的值为2,主内存中受到其他线程的影响变成了3。就算是一直取最新的值也不会是2了啊?
    回复 有任何疑惑可以回复我~ 2018-08-30 16:42:41
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信