Opožděná inicializace singletonu v Javě

Na Wikipedii jsem našel zajímavé řešení návrhového vzoru singleton v Javě. Obecně se nepovažuje za nejšťastnější vytvářet novou instanci opožděně (lazy init) v konstruktoru a doporučuje se statickou inicializací. Když už potřebujete opožděnou inicializaci, tak je vhodné provést to vláknově bezpečnou metodou.

public class Singleton {
// volatile is needed so that multiple thread can reconcile the instance
private volatile static Singleton singleton;

private Singleton(){}

// synchronized keyword has been removed from here
public static Singleton getSingleton(){
// needed because once there is singleton available no need to acquire
// monitor again & again as it is costly
if(singleton==null) {
synchronized(Singleton.class){
// this is needed if two threads are waiting at the monitor at the
// time when singleton was getting instantiated
if(singleton==null)
singleton= new Singleton();
}
}
return singleton;
}

}

Existuje ovšem elegantnější řešení, které je vláknově bezpečné a má kratší zápis.

public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}

/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}

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

Kdo zná pravidla načítání tříd v Javě, pochopí, jak to funguje.
13 July 2010 | java
twitter.com linkedin.com
google.com/+ facebook.com
flickr.com youtube.com