Не буду рассказывать, что такое singleton и для чего он нужен. Расскажу про то, как его писать.
Всегда склонялся к варианту double check, но после статьи про текущую модель памяти в java, мир для меня перестал быть прежним. Оказывается, volatile довольно затратная операция и немного лучше synchronized. Наилучшим же вариантом с ленивой инициализацией будет следующий код:
public final class Singleton {
private Singleton(){};
public static Singleton getInstance(){
return SingletonCreator.INSTANCE;
}
private static class SingletonCreator {
private static final Singleton INSTANCE = new Singleton();
}
}
Этот вариант является thread-safe и lazy.
Потокобезопасный потому что java гарантирует что final поля будут проинициализированы только один раз и никакой потом не увидит null значения.
Ленивым этот вариант является потому что java инициализирует static поля у класса только в момент обращения к данному классу. Класс SingletonCreator ни в каких местах не доступен, кроме метода getInstance.