2016-10-10 43 views
0

我想了解getAndIncrement中的current是如何更新的,下面是这段代码。Java AtomicInteger getAndIncrement()和compareAndSet

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

我明白compareAndSet将比较电流值是否与存储在寄存器中的值,如果是相同的,然后更新接下来在寄存器中的值。

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

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

+6

因为您调用['getAndIncrement()'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndIncrement--),它有点类似于postincrement操作符('i ++')。对于你描述的行为,有['incrementAndGet()'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet--) ,类似于预增量运算符('++ i')。 – Turing85

+0

我所问的是“当前”如何更新为原语,我只看到“当前”指的是更新的值? –

+0

我不完全理解你的评论。 Java是按值传递的,所以'current'永远不会被改变,因此在你给出的例子中'5'将被返回。这回答了你的问题了吗? – Turing85

回答

0

这是为了提高并发性。

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

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

+0

但是current不是一个引用,而是一个原始值,那么在执行返回时,当前的调用是否再次得到()?在这里,我只能看到当前“引用”的值被更新。 –

+0

有人可能会说,只有一个线程能够返回一个特定的值,如果'next'没有同步返回(并溢出asied),因为只有一个线程能够成功调用CAS操作并因此返回一个特定的值。 next值可能不会返回实际的当前值,但可能不需要。 – Turing85

相关问题