Почему статический внутренний класс singleton thread safe

Как говорится в заголовке, почему статический вложенный класс singleton thread safe?

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();    
    }    
}  

Ответ 1

Код, который вы показываете, не является технически потокобезопасным. Этот вид хитроумного кода часто получает зависания.

Код должен выглядеть так:

public class Singleton  {    
    private static class SingletonHolder {    
        public static final Singleton instance = new Singleton();
    }    

    public static Singleton getInstance() {    
        return SingletonHolder.instance;    
    }    
}

Здесь мы назначаем в статическом инициализаторе (SingletonHolder), который будет просматриваться любым потоком, обращаясь к нему с помощью правильного отношения "дожидаться". Там нет ничего особенного в вложенном классе, он просто позволяет использовать внешний класс без непосредственной сборки объекта singleton. Почти наверняка это совершенно бессмысленно, но, похоже, кому-то нравятся.

Как всегда [изменчивые] синглтоны - действительно плохая идея.

Ответ 2

Это поточно-безопасный, поскольку JVM обрабатывает ленивую загрузку вложенного класса.

Однако код, который вы опубликовали, кажется, не использует этот шаблон правильно (вы не должны иметь нулевую проверку), и я думаю, что это фактически нарушает безопасность потока. Вот хорошая статья, где вы можете узнать больше о том, почему этот шаблон работает и как его правильно использовать:

Инициация владельца по требованию