Singleton pattern is used in many projects I've gone through and I implemented it the same way in all the projects just like others did. Luckily for me the many projects could be safely assumed as thread safe projects. Thread safe project for me is a project where no thread programming is required. Before continuing, below is how I implemented singleton pattern.
public class SingletonClassic {
static SingletonClassic instance;
public static SingletonClassic getInstance() {
if (instance == null) {
instance = new SingletonClassic();
}
return instance;
}
}I guess the code above should be familiar to programmers. Now, we delve into the reason of why I spend my time writing this blog. The code above is actually not thread safe, let's consider for example we have 2 threads running. Both are trying to access the singleton above (assume that the singleton isn't accessed yet), the 1st thread already pass the "if (instance == null) {" statement and the thread scheduler thinks that it's the 2nd thread time to run so the 1st thread got paused and the 2nd thread runs. 2nd thread arrive at the "if (instance == null) {" statement, the instance isn't instantiated yet so it enters into the if clause and create an instance and returns the instance. 2nd thread sleeps and 1st thread wakes up and continue where it left before which is creating
another instance.
So, we have a Singleton which is not so Singleton. At this point we see no harm done but if you're a perfectionist, the problem above will annoy you :)
To ease you, here's the solution that I read in some article which unfortunately I forgot (very very unfortunate for me not to keep the link) :
public class SingletonClass {
public static SingletonClass getInstance() {
return SingletonHolder.getInstance();
}
static class SingletonHolder {
static SingletonClass instance;
static {
instance = new SingletonClass();
}
static SingletonClass getInstance() {
return instance;
}
}
}I just go straight to the point here, the reason why the new code above is thread safe is because the static initializer is guaranteed to be thread safe in the jvm specification. It will be initialized only once when the class is loaded.
still confused? let me break it down :
1. SingletonClass.getInstance() is called
2. which in turn will call SingletonHolder.getInstance()
3. at this point static initializer in SingletonHolder will be executed where SingletonClass instance is initialized
4. the new SingletonClass instance is returned, the instance will not be instantiated twice. Guaranteed!
If I ever meet the article again, I will write the name of the guy who found this method here.