关于public final int getAndAddInt(Object var1, long var2, int var4) 方法的一个问题
来源:3-1 线程安全性-原子性-atomic-1
磊磊要酷酷滴
2019-03-27
- 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 两个操作中间尽管会插入其他操作,但要重试好几次的概率其实很小,这里不需要纠结一直会重试下去的可能,这里只能说理论上有可能会重试很多次,实际会很快退出重试的。
012019-03-29 -
Turren
2019-03-27
022019-03-27
相似问题