From Head First design patterns book, the singleton pattern with double checked locking has been implemented as below:
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
I don't understand why volatile
is being used. Doesn't volatile
usage defeat the purpose of using double checked locking i.e performance?
A good resource for understanding why volatile
is needed comes from the JCIP book. Wikipedia has a decent explanation of that material as well.
The real problem is that Thread A
may assign a memory space for instance
before it is finished constructing instance
. Thread B
will see that assignment and try to use it. This results in Thread B
failing because it is using a partially constructed version of instance
.