CAS
Atomic и CAS. Классы вроде AtomicInteger делают операции атомарно без блокировок — через CAS (Compare-And-Swap): «сравни текущее значение с ожидаемым и, если совпало, замени». Не совпало — повтори. Быстрее synchronized на простых счётчиках, потому что нет ожидания замка — поток просто пробует снова.
AtomicInteger count = new AtomicInteger();
count.incrementAndGet(); // атомарно, без synchronized
ForkJoinPool — пул для разбиения большой задачи на подзадачи (на нём работают параллельные стримы); тоже использует похожие безблокировочные приёмы внутри.
Копнуть глубже
ABA-проблема CAS. CAS проверяет «значение равно ожидаемому», но не замечает, что значение могло измениться и вернуться обратно: поток 1 прочитал A, поток 2 поменял A→B→A, поток 1 видит A и думает «ничего не изменилось» — хотя изменение было. Для решения используют AtomicStampedReference — CAS по паре (значение + версия), версия монотонно растёт и её не откатить.
LongAdder vs AtomicLong — когда много потоков обновляют один счётчик, AtomicLong создаёт высокую конкуренцию (все CAS-спинят на одной ячейке памяти). LongAdder хранит несколько ячеек, потоки пишут в разные, при чтении суммирует — значительно быстрее под высокой нагрузкой:
LongAdder hits = new LongAdder();
hits.increment(); // разные потоки пишут в разные cell'ы без конкуренции
long total = hits.sum();