首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicInteger incrementAndGet原子性

AtomicInteger incrementAndGet原子性
EN

Stack Overflow用户
提问于 2014-03-31 15:52:07
回答 6查看 1.2K关注 0票数 7

根据documentation.However,AtomicInteger.incrementAndGet()是原子的,在下面的源代码中,如果另一个线程在“返回下一个”之前交错,该怎么办?“下一步”是不正确的吗?

代码语言:javascript
复制
public final long incrementAndGet() {
    for (;;) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
          return next;
    }
}
EN

回答 6

Stack Overflow用户

发布于 2014-03-31 15:59:37

如果另一个线程是交错的,那么它也会成功地将值加1。

原子性保证您的增量发生,并且如果两个线程尝试增量,那么最终将有两个线程成功(并且递增两个)。它不能保证任何关于未来价值的东西。

在您的场景中,它看起来像下面的代码:

代码语言:javascript
复制
public final long incrementAndGet() {
    for (;;) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next)) {
            // Other thread.
            for (;;) {
                long current2 = get();
                long next2 = current2 + 1;
                if (compareAndSet(current2, next2)) {
                    return next2;
                }
            }
            return next;
        }
    }
}

也就是说,每个线程都有自己的增量值。

票数 6
EN

Stack Overflow用户

发布于 2014-03-31 15:59:33

每次调用都会正确地递增该值,因此它唯一可能影响的就是返回值。

该函数的语义是,它不返回整数的当前值,而是调用incrementAndGet()将整数增加到的值(更新值)。

让我给你举个例子:

代码语言:javascript
复制
public MyClass {
    private AtomicInteger counter;

    public int getNextUniqueIndex() {
        return counter.getAndIncrement();
    }
}

现在,如果您调用getNextUniqueIndex(),它将始终返回一个惟一的值,而不管调用线程或线程交错。这是因为从incrementAndGet()的实现返回的next的值引用了这次incrementAndGet()调用更新的值。

票数 3
EN

Stack Overflow用户

发布于 2014-03-31 15:58:19

什么是“正确”?

下一个值不是AtomicInteger的当前值,而是" current“值递增后的值。

让我们假设下面的模拟(以这种方式,“线程2”在“返回下一个”之前交错了“线程1”)

代码语言:javascript
复制
i = 10
Thread 1
calling 'j = incrementAndGet(i)'
computing incrementAndGet(i) by Thread 1
now i = 11

Thread 2
calling 'm = incrementAndGet(i)'
computing incrementAndGet(i) by Thread 2
now i = 12 

Thread 1
now j = 11 

Thread 2
now m = 12 

Thread 3
calling 'n = incrementAndGet(i)'
// Hey! It should be only with Thread 1 and 2!
now i = 13 and n = 13

事实上,incrementAndGet是原子的。为什么?因为线程1在我10岁的时候调用了incrementAndGet,得到了11。线程2在我11岁的时候调用了incrementAndGet,得到了12。在incrementAndGet之后,调用者获得递增后的结果值。

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

https://stackoverflow.com/questions/22756225

复制
相关文章

相似问题

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