Использует ли AtomicReference в Java блокировки (synchronized) для синхронизации?

«Использует ли AtomicReference в Java блокировки (synchronized) для синхронизации?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, AtomicReference не использует явные блокировки (synchronized). Вместо этого он обеспечивает потокобезопасность с помощью неблокирующих (lock-free) алгоритмов, основанных на CAS (Compare-And-Swap) операциях, поддерживаемых на уровне процессора.

Как это работает:

AtomicReference<String> ref = new AtomicReference<>("initial");
// Атомарно меняем значение, только если текущее равно ожидаемому
boolean success = ref.compareAndSet("initial", "updated");

Метод compareAndSet атомарно выполняет логику: if (currentValue == expectedValue) { currentValue = newValue; return true; } else { return false; }.

Преимущества и особенности:

  • Отсутствие блокировок: Нет риска взаимных блокировок (deadlocks) и снижаются накладные расходы на переключение контекстов.
  • ABA-проблема: Если между чтением значения и попыткой CAS другое поток изменил значение с A на B и обратно на A, CAS всё равно успешно выполнится. Для сценариев, где это критично, используйте AtomicStampedReference или AtomicMarkableReference.
  • Производительность: Эффективно при высокой конкуренции на чтение и редкой записи.

Реализация: Внутри используются низкоуровневые средства JVM, такие как sun.misc.Unsafe или, в современных версиях Java, java.lang.invoke.VarHandle.