Avoid Active Waiting
/** thread safe */
class Counter {
private final AtomicLong count = new AtomicLong();
void increment(long amount) {
if (amount < 1) {
throw new IllegalArgumentException("Only increments!");
}
this.count.addAndGet(amount);
}
}
- AtomicLong is nonblocking (lock-free) but may result in lots of active waiting
/** thread safe */
class Counter {
private final LongAdder count = new LongAdder();
void increment(long amount) {
if (amount < 1) {
throw new IllegalArgumentException("Only increments!");
}
this.count.add(amount);
}
}
- LongAdder uses multiple atomatic longs (multiple stripes), one per thread. The sum of those stripes is the total.
- Sum is not as exact as it is with the AtomicLong, but much higher performance if multiple threads increment simultaneously, eventually consistent