AtomicInteger.incrementAndGet()与AtomicInteger.getAndIncrement()

hyd*_*yde 37 java atomic java.util.concurrent

当返回值不感兴趣时,当忽略返回值时,是否存在(AtomicInteger.getAndIncrement()和实际上不相关的)AtomicInteger.incrementAndGet()方法之间的差异?

我正在考虑哪些差异会更加惯用,以及哪些会减少CPU缓存的负载同步,或其他任何事情,任何事情来帮助决定哪一个比投掷硬币更合理地使用.

ass*_*ias 29

代码基本相同,所以没关系:

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `incrementAndGet()== getAndIncrement()+ 1` (3认同)
  • Doug Lea对每个CPU周期都很着迷:) (3认同)

hyd*_*yde 25

由于没有给出实际问题的答案,这里是基于其他答案(谢谢,upvoted)和Java约定的个人观点:

incrementAndGet()
Run Code Online (Sandbox Code Playgroud)

更好,因为方法名称应以描述操作的动词开头,此处的预期操作仅是增量.

从动词开始是常见的Java约定,也由官方文档描述:

"方法应该是动词,混合大小写,首字母小写,每个内部单词的首字母大写."

  • 如果他们公开了一个简单的`increment()`方法,那就好了,只是为了便于阅读. (4认同)

Joa*_*uer 9

不,没有区别(如果你不关心返回值).

这些方法的代码(在OpenJDK中)的不同之处在于使用return next和使用其他方法return current.

两者都使用compareAndSet完全相同的算法.两者都需要知道旧值和新值.


Iły*_*sov 6

只想添加到现有答案中:可能存在非常小的不明显差异。

如果你看看这个实现

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

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
Run Code Online (Sandbox Code Playgroud)

注意 - 两个函数调用完全相同的函数getAndAddInt,除了+1部分,这意味着在这个实现getAndIncrement中更快。

但是,这是较旧的实现

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
Run Code Online (Sandbox Code Playgroud)

唯一的区别是返回变量,因此两个函数的执行完全相同。