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 forinstance
before it is finished constructinginstance
.Thread B
will see that assignment and try to use it. This results inThread B
failing because it is using a partially constructed version ofinstance
.