В представленном коде есть несколько ошибок:
Что нужно изменить в этом коде, чтобы была корректная потокобезопасная реализация паттерна Синглтон?
В представленном коде есть несколько ошибок:
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Что нужно изменить в этом коде, чтобы была корректная потокобезопасная реализация паттерна Синглтон?
public class Singleton {
private static final Singleton instance;
public Singleton() {
}
public Singleton getInstance() {
if (instance != null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Ответ
В представленном коде есть несколько ошибок:
- Поле
instanceобъявлено какfinal, но инициализируется не сразу — это невозможно. - В методе
getInstance()проверка и синхронизация сделаны неправильно.
Правильная потокобезопасная реализация с ленивой инициализацией и двойной проверкой выглядит так:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// приватный конструктор
}
public static Singleton getInstance() {
if (instance == null) { // первая проверка без синхронизации
synchronized (Singleton.class) {
if (instance == null) { // вторая проверка внутри synchronized
instance = new Singleton();
}
}
}
return instance;
}
}
Ключевые моменты:
instanceдолжна бытьstatic volatileдля корректного видения изменений в разных потоках.- Синхронизация происходит на классе, а не на экземпляре.
- Конструктор приватный, чтобы предотвратить создание экземпляров извне.