AtomicInteger
来源:3-1 线程安全性-原子性-atomic-1
![](http://img1.sycdn.imooc.com/user/545845c40001996c02200220-100-100.jpg)
慕码人1088981
2018-08-29
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吗
1回答
-
Jimin
2018-08-29
你好,这里的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)操作。这样通过无锁自旋的方式不断尝试不断更新直至成功,同时来保证线程安全性,并且跳出当前的循环。在线程竞争不激烈时,可以很快的返回。
0112018-09-01
相似问题