Относительно статического одноэлементного шаблона держателя
Я разработал синглтон разными способами в зависимости от состояния, такого как volatile/lazy singleton, eager singleton, normal singleton и Enum, но, в частности, я хочу знать о статичном шаблоне синтаксиса, показанном ниже.
public static class Singleton {
private static class InstanceHolder {
public static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance() {
return InstanceHolder.instance;
}
}
Просьба сообщить, в каких условиях это выгодно и каковы его преимущества.
Ответы
Ответ 1
Этот шаблон полезен, по крайней мере, для 3 причин:
- Статический factory
- ленивая инициализация
- Защита потолка
JVM откладывает инициализацию класса InstanceHolder до тех пор, пока он фактически не используется, и поскольку Singleton инициализирован статическим инициализатором, дополнительной синхронизации не требуется. Первый вызов getInstance любым потоком заставляет InstanceHolder загружаться и инициализироваться, и в это время инициализация Singleton происходит через статический инициализатор.
Статический шаблон держателя также считается самой умной заменой антипаттера с двойной проверкой.
Ответ 2
Это способ сделать потокобезопасный ленивый синглтон, используя способ загрузки классов JVM. Вы можете узнать больше о том, почему и как правильно его реализовать в блоховской эффективной Java-книге.
Помните, что с точки зрения testable code
синглтоны (и глобальное состояние в целом) не выгодны и их следует избегать.