Какими способами обеспечивается потокобезопасность при реализации паттерна Singleton?
Ответ от нейросети
sobes.tech AI
Потокобезопасность при реализации паттерна Singleton в Java достигается несколькими способами:
-
Использование synchronized
Метод получения экземпляра помечается ключевым словом
synchronized, чтобы обеспечить эксклюзивный доступ:public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }Недостаток — накладные расходы на синхронизацию при каждом вызове.
-
Double-checked locking
Проверка экземпляра происходит дважды — до и после синхронизации, чтобы снизить накладные расходы:
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }Ключевое слово
volatileгарантирует корректную работу с памятью. -
Использование статического внутреннего класса (Initialization-on-demand holder idiom)
Этот способ ленивой и потокобезопасной инициализации не требует синхронизации:
public class Singleton { private Singleton() {} private static class Holder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; } }Класс
Holderзагружается и инициализируется только при первом вызовеgetInstance(). -
Enum Singleton
Использование перечисления гарантирует потокобезопасность и защиту от сериализации:
public enum Singleton { INSTANCE; // методы }
Каждый из этих способов обеспечивает потокобезопасность, выбор зависит от требований к производительности и удобству.