Usually I use the first implementation. Couple of days ago I found another.
Can anyone explain me the difference between these 2 implementations ?
The 2nd implementation is thread safe?
What is the advantage of using inner class in the 2nd example?
//--1st Impl
public class Singleton{
private static Singleton _INSTANCE;
private Singleton() {}
public static Singleton getInstance(){
if(_INSTANCE == null){
synchronized(Singleton.class){
if(_INSTANCE == null){
_INSTANCE = new Singleton();
}
}
}
return _INSTANCE;
}
}
//--2nd Impl
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton _INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder._INSTANCE;
}
}
The first implementation uses what is called a “double checked lock”. This is a Very Bad Thing. It looks thread-safe, but in fact it is not.
The second implementation is, indeed, thread-safe.
The explanation for why the first implementation is broken is fairly involved, so I’d recommend you get a copy of Brian Goetz’s Java Concurrency in Practice for a detailed explanation. The short version is that the compiler is allowed to assign the
_INSTANCEvariable before the constructor has completed, which can cause a second thread to see a partially-constructed object.