Chapter 1: Protect Your Shared Mutable State

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