Atomics and compare-and-swap question 60 of 180 senior
How would you write a thread-safe non-blocking counter without atomics?
- It is impossible without
synchronized - Correct: With a
VarHandle(or, historically,Unsafe) doing the compare-and-set on a volatile field yourself - With a
ThreadLocal - With
Collections.synchronizedList
The atomic classes are thin wrappers. Since Java 9 the supported way to do it yourself is VarHandle:
private volatile long value;
private static final VarHandle VALUE;
static {
try {
VALUE = MethodHandles.lookup().findVarHandle(Counter.class, "value", long.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
void increment() {
long old;
do {
old = value;
} while (!VALUE.compareAndSet(this, old, old + 1));
}
VarHandle also exposes the weaker modes that make this interesting at the senior level:
getPlain, getOpaque, getAcquire/setRelease and the full volatile mode. Release/acquire is
enough for most publication and is cheaper than a full fence on weakly ordered hardware. In real code,
use AtomicLong unless you have measured a reason not to.
Quiz yourself on Atomics and compare-and-swap Suggest a correction