【问题标题】:Java AtomicInteger getAndIncrement() and compareAndSetJava AtomicInteger getAndIncrement() 和 compareAndSet
【发布时间】:2017-02-19 04:36:48
【问题描述】:

我试图了解 getAndIncrement 中的 current 是如何更新的,这是那段代码。

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

我知道 compareAndSet 会比较当前值是否与寄存器中存储的值相同,如果相同则用 next 更新寄存器中的值。

我不明白的部分是为什么它不返回next 而不是current

进入循环时,current被设置为int,current不是参考值,所以如果current初始化为5,那么返回current时,应该也是5吗?或者当它返回current时,current会再次调用get()从寄存器中获取更新的值?

【问题讨论】:

  • 因为您调用getAndIncrement(),这有点类似于后增量运算符 (i++)。对于您描述的行为,有 incrementAndGet(),它类似于预增量运算符 (++i)。
  • 我要问的是“current”是如何作为原语更新的,我只看到“current”所指的值被更新了?
  • 我不完全理解您的评论。 Java 是按值传递的,因此 current 永远不会被更改,因此在您给定的示例中 5 将被返回。这能回答你的问题吗?
  • 啊,我知道了,非常感谢。

标签: java multithreading nonblocking compare-and-swap


【解决方案1】:

是为了提高并发性。

如果它返回next,则该方法必须具有同步代码,否则另一个线程可以在设置它和返回它之间修改该值。

不返回next,只有实际修改需要同步,把同步的责任和优化放在一处; compareAndSet()。当方法之间共享同步时,协调安全状态更改要复杂得多。

【讨论】:

  • 但是 current 不是引用而是原始值,在 return 执行时 current 会再次调用 get() 吗?在这里我只能看到当前“引用”到的值被更新了。
  • 如果next 在没有同步的情况下返回(并且溢出),有人可能会争辩说只有一个线程能够返回一个特定的值,因为只有一个线程能够成功调用 CAS-操作,因此返回一个特定的值。 next 值可能不会返回实际的当前值,但这可能不是我们想要的。
猜你喜欢
  • 2013-11-14
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
  • 2023-03-25
  • 2013-10-14
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多