How do CAS-related changes to the AtomicLong class in Java 8?

Prior to Java 8, the code for CAS in the AtomicLong class was:

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

But now it has been changed to one inner line:

public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}

What advantage does this code have over the first? How does this new code work?

+4
source share
3 answers

The reason is branch prediction in the loop. In conditions of high competition, the CAS cycle is often interrupted, and the branch predictor begins to predict that the execution path will remain in the cycle, which will lead to repeated flushing of the pipeline when the CAS eventually succeeds. It also speeds up the loop when what you really want is a rollback when CAS fails, not speedup.

. https://blogs.oracle.com/dave/entry/atomic_fetch_and_add_vs.

+6

unsafe.getAndAddLong JVM, JIT . x86 CPU LOCK XADD.

+5

As described in the link provided by Jim, in Java 8 incrementAndGet and other methods use hardware support for the lock, fetch, and add command.

0
source

All Articles