英文:
replace `getIntVolatile(Object var1, long var2)` with `getInt(Object var1, long var2)` in the implementation of incrementAndGet() in java
问题
根据 JDK 文档,AtomicInteger 类的 incrementAndGet() 方法的实现如下所示:
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 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;
}
如果将 getIntVolatile(Object var1, long var2) 方法替换为 getInt(Object var1, long var2) 方法,会发生什么情况?
我认为 getIntVolatile(Object var1, long var2) 方法是不必要的,因为操作的变量是一个 volatile 变量,getInt(Object var1, long var2) 方法能够读取到最新的值。
英文:
According the jdk ,the implementation of the method incrementAndGet() of AtomicInteger class is as follows:
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 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;
}
What happens if the getIntVolatile(Object var1, long var2)
method is replaced by getInt(Object var1, long var2)
method?
What I think is that the getIntVolatile(Object var1, long var2)
method is unnecessary, as the operated variable is a volatile variable,the getInt(Object var1, long var2)
is able to read the latest value.
答案1
得分: 1
看一下 incrementAndGet
做了什么:
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
unsafe
并不知道在 valueOffset
处有一个 volatile
字段,它必须将其视为这样处理。因此,这段代码(我没有使用 var2
之类的变量,而是真实的源代码):
v = getIntVolatile(o, offset);
肯定看起来是为了防止一些可能的重排序。假设你用 getInt
替换掉 getIntVolatile
:
do {
v = getInt(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
由于这里没有 volatile 语义,编译器可以将读取移到循环外:
int v = getInt(o, offset);
do {
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
如果它这样做了,你可能会陷入一个无限循环,相当简单。
英文:
Look at what incrementAndGet
does:
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
unsafe
has no idea that at the valueOffset
there is a volatile
field and it must treat it as such. So, this (I am not using var2
and the like, but the real source code):
v = getIntVolatile(o, offset);
surely looks like protects against some possible re-orderings. Let's say you replace that getIntVolatile
with getInt
:
do {
v = getInt(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
Since there are no volatile semantics here, the compiler can move the read out of the loop:
int v = getInt(o, offset);
do {
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
If it does that, you can end-up in an infinite loop, pretty trivially.
答案2
得分: 1
Unsafe
类中的普通 getXXX
/putXXX
方法并不考虑 volatile
关键字。它们总是执行普通的加载/存储操作,没有内存可见性约束。
英文:
Plain getXXX
/putXXX
methods in the Unsafe
class, do not take the volatile
keyword into account. They always perform a plain load/store, without memory visibility constraints.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论