是否存在无法用AtomicInteger.accumulateAndGet()代替AtomicInteger.updateAndGet()的情况,还是只是方便方法引用?

这是一个简单的示例,其中我看不到任何功能上的差异:

AtomicInteger i = new AtomicInteger();
i.accumulateAndGet(5, Math::max);
i.updateAndGet(x -> Math.max(x, 5));

显然,getAndUpdate()getAndAccumulate()也是如此。

最佳答案

如有疑问,您可以查看implementation:

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;
}

它们仅在单行中有所不同,显然accumulateAndGet可以通过updateAndGet轻松表达:
public final int accumulateAndGet(int x,
                                  IntBinaryOperator accumulatorFunction) {
    return updateAndGet(prev -> accumulatorFunction.applyAsInt(prev, x));
}

因此,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

07-27 14:33