在Java 8之前,AtomicLong类中的CAS代码是:

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

但是现在它已更改为单个内在行:
public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}

此代码相对于前者有什么优势?这个新代码如何工作?

最佳答案

原因是循环上的分支预测。在争用较高的情况下,CAS循环经常失败,分支预测器开始预测执行路径将停留在循环中,从而在CAS最终成功时导致大量流水线刷新。当您真正想要的是CAS失败时的退避(而不是加速)时,这也会加快循环。

有关更多详细信息,请参见https://blogs.oracle.com/dave/entry/atomic_fetch_and_add_vs

07-28 01:40
查看更多