AtomicInteger.updateAndGet()和AtomicInteger.accumulateAndGet()之间是否存在任何功能差异?

shm*_*sel 13 java lambda atomic java-8 atomicinteger

是否存在AtomicInteger.accumulateAndGet()无法替换的场景AtomicInteger.updateAndGet(),或者仅仅是方法引用的便利?

这是一个简单的例子,我没有看到任何功能差异:

AtomicInteger i = new AtomicInteger();
i.accumulateAndGet(5, Math::max);
i.updateAndGet(x -> Math.max(x, 5));
Run Code Online (Sandbox Code Playgroud)

显然,同样也适用于getAndUpdate()getAndAccumulate().

Tag*_*eev 9

如有疑问,您可以查看实施情况:

public final int accumulateAndGet(int x,
                                  IntBinaryOperator accumulatorFunction) {
    int prev, next;
    do {
        prev = get();
        next = accumulatorFunction.applyAsInt(prev, x);
    } while (!compareAndSet(prev, next));
    return next;
}

public final int updateAndGet(IntUnaryOperator updateFunction) {
    int prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
    } while (!compareAndSet(prev, next));
    return next;
}
Run Code Online (Sandbox Code Playgroud)

它们只有单线不同,显然accumulateAndGet可以通过updateAndGet以下方式轻松表达:

public final int accumulateAndGet(int x,
                                  IntBinaryOperator accumulatorFunction) {
    return updateAndGet(prev -> accumulatorFunction.applyAsInt(prev, x));
}
Run Code Online (Sandbox Code Playgroud)

所以updateAndGet是一些更基本的操作,accumulateAndGet是一个有用的捷径.如果您x没有真正的最终结果,这样的捷径可能会特别有用:

int nextValue = 5;
if(something) nextValue = 6;
i.accumulateAndGet(nextValue, Math::max);
// i.updateAndGet(prev -> Math.max(prev, nextValue)); -- will not work
Run Code Online (Sandbox Code Playgroud)