[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-double-checked-locking-singleton":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":20,"progress":21,"seo":22},280,"chto-takoe-double-checked-locking-singleton",8,"mnogopotochnost","Многопоточность","🔀","Что такое double checked locking Singleton?","\u003C!-- grade: 4\u002F5 — корректно описана роль volatile; добавлены пояснения по модели памяти -->\n\n**Double Checked Locking (DCL)** — это паттерн ленивой инициализации Singleton, который оптимизирует производительность за счёт того, что блокировка захватывается только при первом создании экземпляра.\n\n**Проблема:** простая синхронизация (`synchronized getInstance()`) работает, но каждый вызов `getInstance()` проходит через блокировку, даже когда объект уже создан. DCL решает это, проверяя наличие экземпляра дважды — до и после входа в синхронизированный блок.\n\n```java\nclass DoubleCheckedLockingSingleton {\n    private static volatile DoubleCheckedLockingSingleton instance;\n\n    static DoubleCheckedLockingSingleton getInstance() {\n        DoubleCheckedLockingSingleton current = instance; \u002F\u002F (1) Первая проверка — без блокировки\n        if (current == null) {\n            synchronized (DoubleCheckedLockingSingleton.class) {\n                current = instance; \u002F\u002F (2) Вторая проверка — под блокировкой\n                if (current == null) {\n                    instance = current = new DoubleCheckedLockingSingleton(); \u002F\u002F (3) Создание\n                }\n            }\n        }\n        return current;\n    }\n}\n```\n\n**Почему `volatile` обязателен?** Без `volatile` возможна ситуация, при которой JVM переупорядочит инструкции при создании объекта (шаг 3). Создание объекта состоит из нескольких действий:\n\n1. Выделение памяти\n2. Инициализация полей (вызов конструктора)\n3. Присвоение ссылки переменной `instance`\n\nБез `volatile` JVM может выполнить шаги в порядке 1 → 3 → 2. Тогда другой поток, выполняя проверку `if (current == null)`, увидит ненулевую ссылку на **не полностью сконструированный объект** и начнёт его использовать.\n\n`volatile` гарантирует:\n- Запрет переупорядочивания (запись в `volatile`-поле happens-before чтения из него).\n- Видимость: все потоки видят актуальное значение.\n\n**Зачем локальная переменная `current`?** Обращение к `volatile`-полю дороже обращения к локальной переменной. Присвоив `instance` в локальную переменную, мы читаем `volatile` только один раз на «быстром пути» (когда объект уже создан), что улучшает производительность.\n\n> **Аналогия:** DCL — это как проверка запертой двери. Сначала вы смотрите (без ключа): если дверь открыта — входите сразу. Если закрыта — достаёте ключ (синхронизация), открываете, и снова проверяете — вдруг кто-то открыл, пока вы искали ключ.\n\n> **На собеседовании** классический вопрос: «Почему DCL без volatile сломан?» Ответ должен включать упоминание переупорядочивания инструкций JVM и happens-before. Также стоит упомянуть, что эта проблема была частично решена в JDK 1.5 (новая спецификация JMM), но рекомендация использовать `volatile` остаётся в силе.","","middle",[15,16,17,18,19],"Singleton","double-checked-locking","паттерны","volatile","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":33,"featuredSnippetReady":34},"Double checked locking Singleton в Java — потокобезопасный Одиночка — Gymterview","Double checked locking оптимизирует Singleton, блокируясь только при первом создании экземпляра. Обязательно использование volatile для корректности.","Double Checked Locking Singleton — зачем volatile обязателен","DCL Singleton блокируется только при первом создании экземпляра. Без volatile другой поток может получить не полностью сконструированный объект.",[28,29,30,31,32],"double checked locking Java","Singleton потокобезопасный","volatile Singleton","DCL паттерн","Одиночка Java","Double checked locking Singleton — способ создания потокобезопасного Одиночки, оптимизирующий производительность: блокировка происходит только при первом создании экземпляра. Требование volatile обязательно — без него возможна ситуация, при которой другой поток получит не полностью сконструированный объект из-за модели памяти Java.",true]