Ответ
Атомарные классы из пакета java.util.concurrent.atomic предоставляют возможность выполнять одиночные потокобезопасные операции над переменными без использования блокировок (lock-free), что часто приводит к более высокой производительности в условиях высокой конкуренции.
Принцип работы: В основе лежат аппаратные инструкции CAS (Compare-And-Swap), которые атомарно сравнивают и обновляют значение в памяти.
Пример: AtomicInteger vs synchronized
// С использованием AtomicInteger
AtomicInteger atomicCounter = new AtomicInteger(0);
atomicCounter.incrementAndGet(); // Атомарная операция без блокировок
// С использованием synchronized
class SynchronizedCounter {
private int count = 0;
public synchronized void increment() { count++; } // Блокировка всего объекта
public synchronized int get() { return count; }
}
Ключевые преимущества атомарных классов:
- Отсутствие блокировок (Non-blocking): Потоки не приостанавливаются, а повторяют операцию (в цикле), если значение изменилось другим потоком. Это уменьшает накладные расходы на переключение контекста.
- Избегание deadlock: Невозможность взаимной блокировки, так как нет захвата нескольких мониторов.
- Гарантия видимости (happens-before): Все операции обеспечивают ту же семантику видимости изменений, что и
volatile. - Богатый API: Сложные атомарные операции в одну инструкцию:
AtomicInteger atomic = new AtomicInteger(10); // Атомарно: прочитать, умножить на 2, сохранить, вернуть результат int doubled = atomic.updateAndGet(x -> x * 2); // Результат: 20
Когда использовать:
- Для простых атомарных операций (инкремент, сравнение с обменом).
- В качестве volatile-переменных с атомарными обновлениями.
- Для реализации неблокирующих алгоритмов.
Ограничения: Атомарные классы не подходят для сложных составных операций, зависящих от нескольких переменных. В таких случаях нужны synchronized или java.util.concurrent.locks.