Почему статический внутренний класс синглтонового потока безопасен
Как видно из названия, почему статический вложенный класс одноэлементный поток безопасен?
public class Singleton
{
private static class SingletonHolder
{
public static Singleton instance = null;
public static Singleton getInstance(){
if (null == instance) {
instance = new Singleton();
}
}
}
public static Singleton getInstance()
{
return SingletonHolder.getInstance();
}
}
2 ответа
Код, который вы показываете, не является технически потокобезопасным. Этот вид хитрого кода часто получает искажения.
Код должен выглядеть так:
public class Singleton {
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
Здесь мы назначаем в статическом инициализаторе (из SingletonHolder
), который будет виден любому потоку, обращающемуся к нему с правильными отношениями " происходит до". Во вложенном классе нет ничего особенного, он просто позволяет использовать внешний класс без немедленного создания объекта-одиночки. Почти наверняка это совершенно бессмысленно, но, похоже, это нравится некоторым людям.
Как всегда [изменчивые] синглтоны - действительно плохая идея.
Он ориентирован на многопотоковое исполнение, поскольку JVM выполняет ленивую загрузку вложенного класса.
Тем не менее, код, который вы разместили, похоже, не использует этот шаблон правильно (вы не должны иметь нулевую проверку), и я думаю, что это фактически нарушает безопасность потока. Вот хорошая статья, где вы можете прочитать больше о том, почему этот шаблон работает и как правильно его использовать: