首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicInteger.updateAndGet()和AtomicInteger.accumulateAndGet()之间有什么功能区别吗?

AtomicInteger.updateAndGet()和AtomicInteger.accumulateAndGet()之间有什么功能区别吗?
EN

Stack Overflow用户
提问于 2016-03-15 21:40:16
回答 2查看 7.2K关注 0票数 14

是否有任何AtomicInteger.accumulateAndGet()不能被AtomicInteger.updateAndGet()替换的场景,或者它只是方法引用的方便呢?

下面是一个简单的例子,在这里我看不到任何功能上的区别:

代码语言:javascript
复制
AtomicInteger i = new AtomicInteger();
i.accumulateAndGet(5, Math::max);
i.updateAndGet(x -> Math.max(x, 5));

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-16 01:03:06

当有疑问时,您可以查看实现

代码语言:javascript
复制
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很容易地表达出来。

代码语言:javascript
复制
public final int accumulateAndGet(int x,
                                  IntBinaryOperator accumulatorFunction) {
    return updateAndGet(prev -> accumulatorFunction.applyAsInt(prev, x));
}

因此,updateAndGet是更基本的操作,而accumulateAndGet是一个有用的快捷方式。如果您的x不是有效的最终结果,这样的快捷方式可能特别有用:

代码语言:javascript
复制
int nextValue = 5;
if(something) nextValue = 6;
i.accumulateAndGet(nextValue, Math::max);
// i.updateAndGet(prev -> Math.max(prev, nextValue)); -- will not work
票数 10
EN

Stack Overflow用户

发布于 2016-04-21 11:55:52

在某些情况下,可以使用accumulateAndGet避免创建实例。

这实际上并不是一个功能上的区别,但了解它可能是有用的。

请考虑以下示例:

代码语言:javascript
复制
void increment(int incValue, AtomicInteger i) {
    // The lambda is closed over incValue. Because of this the created
    // IntUnaryOperator will have a field which contains incValue. 
    // Because of this a new instance must be allocated on every call
    // to the increment method.
    i.updateAndGet(value -> incValue + value);

    // The lambda is not closed over anything. The same
    // IntBinaryOperator instance can be used on every call to the 
    // increment method.
    //
    // It can be cached in a field, or maybe the optimizer is able 
    // to reuse it automatically.
    IntBinaryOperator accumulatorFunction =
            (incValueParam, value) -> incValueParam + value;

    i.accumulateAndGet(incValue, accumulatorFunction);
}

实例创建通常并不昂贵,但在性能敏感的位置中使用非常频繁的短期操作可能很重要。

有关何时重用lambda实例的更多信息可以在这个答案中找到。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36022739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档