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.