Как работает метод incrementAndGet() в AtomicInteger и в чем его преимущества?

«Как работает метод incrementAndGet() в AtomicInteger и в чем его преимущества?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Метод incrementAndGet() класса AtomicInteger атомарно увеличивает текущее значение на единицу и возвращает обновленное значение. Его главное преимущество — потокобезопасность без использования явных блокировок (synchronized).

Принцип работы (на основе CAS): Под капотом используется аппаратная инструкция Compare-And-Swap (CAS).

  1. Метод читает текущее значение volatile-переменной value.
  2. Вычисляет новое значение (current + 1).
  3. Выполняет операцию CAS: если значение value все еще равно current, оно заменяется на current + 1. В противном случае (значение изменилось другим потоком) шаги 1-3 повторяются в цикле.

Пример использования:

import java.util.concurrent.atomic.AtomicInteger;

public class CounterExample {
    private final AtomicInteger threadSafeCounter = new AtomicInteger(0);

    public void handleRequest() {
        // Атомарный инкремент и получение нового значения
        int requestId = threadSafeCounter.incrementAndGet();
        System.out.println("Обрабатываем запрос #" + requestId);
    }
}

Аналог с synchronized (менее эффективный):

public class SynchronizedCounter {
    private int counter = 0;

    public synchronized int incrementAndGet() {
        return ++counter; // Блокировка всего объекта на время операции
    }
}

Ключевые преимущества AtomicInteger.incrementAndGet():

  1. Неблокирующий алгоритм: Потоки не "засыпают" при конкуренции, а повторяют попытку (оптимистичная блокировка). Это дает выигрыш в производительности при высокой конкуренции.
  2. Атомарность: Операция "чтение-изменение-запись" выполняется как единое целое, исключая состояние гонки (race condition).
  3. Масштабируемость: Лучше масштабируется на многоядерных процессорах по сравнению с synchronized.

Семейство методов:

  • getAndIncrement() — увеличивает и возвращает старое значение (постфиксный инкремент).
  • decrementAndGet() / getAndDecrement() — для атомарного декремента.
  • addAndGet(int delta) — для атомарного прибавления произвольного числа.