Получить доступ

Чем volatile отличается от synchronized?

MiddleМногопоточность
Коротко

volatile — видимость и порядок для одной переменной без блокировки. synchronized — видимость плюс взаимное исключение: блок целиком выполняется одним потоком, поэтому составные действия становятся атомарными.

  • volatile не блокирует и не защищает инварианты из нескольких полей
  • synchronized — вход и выход из монитора тоже дают happens-before
  • volatile дешевле, synchronized универсальнее

А ещё Проверить-и-изменить (check-then-act) требует synchronized или атомарных классов

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

volatile применяется к полю. Гарантирует, что запись видна остальным потокам и операции не переставляются вокруг неё. Поток не ждёт: обращение стоит чуть дороже обычного, без блокировки.

synchronized применяется к блоку или методу и захватывает монитор объекта. Пока один поток внутри, остальные с тем же монитором ждут в состоянии BLOCKED. Освобождение монитора и последующий захват задают happens-before: всё, что сделал первый поток, видно следующему.

Пример, где volatile не хватает:

volatile int balance;
void withdraw(int x) {
    if (balance >= x) balance -= x;   // два потока пройдут проверку одновременно
}

Каждое отдельное чтение и запись видны, но проверка и изменение не атомарны вместе. Нужен synchronized или CAS-цикл.

Когда что:

  • флаг остановки, публикация неизменяемого объекта — volatile;
  • счётчик — AtomicInteger;
  • несколько связанных полей, check-then-act — synchronized или Lock.

Что хотят услышать

  • Видимость против взаимного исключения.
  • Пример гонки check-then-act.
  • Когда достаточно volatile.

Частые ошибки

  • «volatile делает операции атомарными».

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗volatile делает составные операции атомарными, synchronized — нет
  • ✗Это синонимы
  • ✓volatile даёт видимость/упорядочивание для одной переменной, но НЕ атомарность; synchronized — взаимное исключение + видимость
  • ✗synchronized работает только с примитивами

Что спросят дальше

  • Что такое happens-before?
  • Когда выбрать AtomicInteger?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем