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

Почему в double-checked locking поле instance обязано быть volatile?

SeniorJVM и сборка мусора
Коротко

new Singleton() — три шага: выделить память, выполнить конструктор, присвоить ссылку. Без volatile присвоение может опередить конструктор, и второй поток на первой проверке (вне synchronized) получит недостроенный объект.

  • volatile запрещает это переупорядочивание и даёт happens-before
  • Проще и надёжнее — holder-класс (ленивая инициализация загрузчиком) или enum
  • В Java 1.4 и раньше volatile не спасал — модель памяти исправлена в Java 5

А ещё Локальная переменная уменьшает число volatile-чтений

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

Подробно

Разложи new Singleton() на три шага: выделить память, отработать конструктор, присвоить ссылку — операция не атомарна. Без volatile модель памяти разрешает переупорядочивание, при котором ссылка присваивается до завершения конструктора. Тогда второй поток на первой (небезопасной) проверке видит не нулевую ссылку, пропускает синхронизацию и получает частично инициализированный объект — с полями по умолчанию вместо реальных значений. volatile закрывает дыру, потому что запись в него happens-before последующего чтения и запрещает такое переупорядочивание. Сильное завершение — что в реальном коде проще взять enum-синглтон или static holder, где ленивость обеспечивают правила инициализации классов, и DCL писать вручную не нужно.

Пример

private static volatile Singleton instance;
static Singleton get() {
    Singleton r = instance;
    if (r == null) {
        synchronized (Singleton.class) {
            r = instance;
            if (r == null) instance = r = new Singleton();
        }
    }
    return r;
}

// проще:
class Holder { static final Singleton INSTANCE = new Singleton(); }

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

  • Три шага создания и опасное переупорядочивание.
  • Роль volatile.
  • Альтернативы: holder и enum.

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

  • Объяснять только через видимость, не упоминая переупорядочивание.
  • Считать, что достаточно synchronized на второй проверке.

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

  • Почему static holder ленив без единой блокировки?
  • Что даёт final-поле в терминах безопасной публикации?

Разбор темы

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

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

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

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

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