Java AtomicInteger的getAndIncrement实现

Java AtomicInteger的getAndIncrement实现,java,synchronization,atomic,volatile,Java,Synchronization,Atomic,Volatile,AtomicInteger的getAndIncrement实现执行以下操作: public final int getAndIncrement() { for (;;) { int current = get(); // Step 1 , get returns the volatile variable int next = current + 1; if (compareAndSet(current, next))

AtomicInteger的getAndIncrement实现执行以下操作:

public final int getAndIncrement() {
    for (;;) {
        int current = get(); // Step 1 , get returns the volatile variable
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    } }
它不是AvoratileVariable++的等价物吗?(我们知道这不是正确的用法)。如果没有同步,我们如何确保这个完整的操作是原子的?如果在步骤1中读取变量“current”后volatile变量的值发生变化,该怎么办?

此调用中的“秘密酱”是:

compareAndSet(current, next)

如果读取后同时更改了原始的volatile值,则操作将失败(并返回
false
),迫使代码继续循环。

一些ISA(特别是x86)直接提供原子添加(或fetch_add),如``mov eax,1`
lock add[rdi],eax
(memory+=eax,register=内存中的旧值)。这不需要任何重试循环,因此它只需等待以独占方式访问缓存线(就像任何存储一样)。一个好的JVM将有一个特定于x86的函数实现。另见。当然,大多数非x86 ISA实际上使用LL/SC()而不是CAS(比较和交换)作为其原子基本构建块,因此,一个好的JVM将使实现更加高效,并在add周围使用LL/SC重试循环,而不是像实际使用此代码时可能会得到的那样,使用实际的CA(根据LL/SC实现)。但与完全在x86上避免重试循环相比,这没什么大不了的。