[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-kak-sozdat-potokobezopasnyy-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},281,"kak-sozdat-potokobezopasnyy-singleton",8,"mnogopotochnost","Многопоточность","🔀","Как создать потокобезопасный Singleton?","\u003C!-- grade: 4\u002F5 — хороший обзор способов; добавлены плюсы\u002Fминусы каждого подхода -->\n\nСуществует несколько способов создания потокобезопасного Singleton в Java, каждый со своими компромиссами:\n\n**1. Static field (Eager initialization)**\n\n```java\npublic class Singleton {\n    public static final Singleton INSTANCE = new Singleton();\n}\n```\n\nЭкземпляр создаётся при загрузке класса. Класс-загрузчик гарантирует потокобезопасность инициализации.\n- **Плюс:** простота, гарантированная потокобезопасность.\n- **Минус:** экземпляр создаётся, даже если он никогда не будет использован (eager).\n\n**2. Enum**\n\n```java\npublic enum Singleton {\n    INSTANCE;\n\n    public void doSomething() { \u002F* ... *\u002F }\n}\n```\n\n- **Плюс:** самый лаконичный способ, защита от десериализации и рефлексии «из коробки» (JVM гарантирует уникальность enum-констант).\n- **Минус:** невозможно наследование; enum загружается eager; не все считают использование enum для Singleton идиоматичным.\n- **Рекомендация Джошуа Блоха** (Effective Java): «enum — лучший способ реализации Singleton».\n\n**3. Synchronized Accessor**\n\n```java\npublic class Singleton {\n    private static Singleton instance;\n\n    public static synchronized Singleton getInstance() {\n        if (instance == null) {\n            instance = new Singleton();\n        }\n        return instance;\n    }\n}\n```\n\n- **Плюс:** ленивая инициализация.\n- **Минус:** каждый вызов `getInstance()` проходит через `synchronized` — избыточная блокировка после первого создания.\n\n**4. Double Checked Locking + volatile**\n\n```java\npublic class Singleton {\n    private static volatile Singleton instance;\n\n    public static Singleton getInstance() {\n        Singleton localInstance = instance;\n        if (localInstance == null) {\n            synchronized (Singleton.class) {\n                localInstance = instance;\n                if (localInstance == null) {\n                    instance = localInstance = new Singleton();\n                }\n            }\n        }\n        return localInstance;\n    }\n}\n```\n\n- **Плюс:** ленивая инициализация, блокировка только при первом создании.\n- **Минус:** сложность кода, необходимость `volatile`.\n\n**5. On Demand Holder Idiom (Initialization-on-demand holder)**\n\n```java\npublic class Singleton {\n    private static class Holder {\n        static final Singleton INSTANCE = new Singleton();\n    }\n\n    public static Singleton getInstance() {\n        return Holder.INSTANCE;\n    }\n}\n```\n\n- **Плюс:** ленивая инициализация (вложенный класс загружается только при первом вызове `getInstance()`), потокобезопасность гарантирована JLS (спецификация загрузки классов), никакой синхронизации при доступе.\n- **Минус:** не защищён от рефлексии и десериализации (в отличие от enum).\n\n**Сравнительная таблица:**\n\n| Способ | Ленивость | Защита от рефлексии | Защита от десериализации | Сложность |\n|---|---|---|---|---|\n| Static field | Нет | Нет | Нет | Минимальная |\n| Enum | Нет | Да | Да | Минимальная |\n| Synchronized | Да | Нет | Нет | Низкая |\n| DCL + volatile | Да | Нет | Нет | Средняя |\n| Holder Idiom | Да | Нет | Нет | Низкая |\n\n> **На собеседовании** часто спрашивают: «Какой способ лучше?» Ответ зависит от контекста. Для большинства случаев — **Enum** (если не нужно наследование) или **Holder Idiom** (если нужна ленивость и привычный класс). DCL уместен, если нужно передать параметры в конструктор при первом вызове.","","middle",[15,16,17,18,19],"потокобезопасность","Singleton","паттерны","enum","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":33,"featuredSnippetReady":34},"Как создать потокобезопасный Singleton в Java — 5 способов — Gymterview","Пять способов создания потокобезопасного Singleton: static field, enum, synchronized accessor, double checked locking + volatile, On Demand Holder Idiom.","5 способов создать потокобезопасный Singleton в Java","Static field, Enum, Synchronized Accessor, Double Checked Locking + volatile, On Demand Holder Idiom — все варианты потокобезопасного Singleton.",[28,29,30,31,32],"потокобезопасный Singleton Java","Singleton enum","Holder Idiom","Singleton паттерн","thread-safe Singleton","Существует пять основных способов: 1) Static field — public static final поле, 2) Enum — использование перечисления, 3) Synchronized Accessor — synchronized метод getInstance(), 4) Double Checked Locking с volatile, 5) On Demand Holder Idiom — использование статического внутреннего класса, экземпляр которого инициализируется при первом обращении.",true]