Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How CAS related changes in AtomicLong class in Java 8 work?

Prior to Java 8 the code for CAS in 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 single intrinsic line:

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

What advantage this code has over the former? How does this new code work?

like image 203
akhil_mittal Avatar asked Mar 25 '15 06:03

akhil_mittal


1 Answers

The reason is branch prediction on the loop. Under high contention the CAS loop fails often and the branch predictor starts to predict the execution path will stay in the loop, causing lots of pipeline flushing when the CAS eventually succeeds. Also this speeds up the loop when what you really want is a backoff when CAS fails, not a speedup.

See https://blogs.oracle.com/dave/entry/atomic_fetch_and_add_vs for a more detailed treatment.

like image 105
Jim Garrison Avatar answered Nov 15 '22 03:11

Jim Garrison