Один общий (1, 2) способ реализации singleton использует внутренний класс с статический член:
public class Singleton {
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
private Singleton() {
//...
}
}
Эта реализация называется лениво инициализированной и потокобезопасной. Но что именно гарантирует безопасность потока? JLS 17, который имеет дело с Threads and Locks, не говорит о том, что статические поля имеют какие-либо отношения до и после. Как я могу быть уверен, что инициализация произойдет только один раз и что все потоки будут видеть один и тот же экземпляр?