Tags
Singleton pattern can be implemented in many ways. One of them is making constructor private and having another factory method to get instance. For example
public class OldSingleton { private static OldSingleton instance = null; private OldSingleton() { } public static OldSingleton getInstance() { if(instance == null) instance = new OldSingleton(); return instance; } }
Or
public class OldSingleton { private static final OldSingleton instance = new OldSingleton(); private OldSingleton() { } public static OldSingleton getInstance() { return instance; } }
Both has pros and cons, first one is not thread safe and the second creates the Singleton Object even before it is actually required. Some times we refine our first approach to make it thread safe, so we made getInstance() method syncronized
public class OldSingleton { private static OldSingleton instance = null; private OldSingleton() { } public static synchronized OldSingleton getInstance() { if(instance == null) instance = new OldSingleton(); return instance; } }
Now due to this synchronized method applications performance degrades. Due to this sync method many threads has to wait to execute getInstance() method. So lets do one more refinement by fine grained locking or say using double check algo
public class OldSingleton { private static OldSingleton instance = null; private OldSingleton() { } public static OldSingleton getInstance() { if(instance == null) { synchronized (OldSingleton.class) { if(instance == null) instance = new OldSingleton(); } } return instance; } }
And still people have found this double check algorithm broken in some case.
There is tons of argument about how to implement single and which one is better than other. But there is a SIMPLE and EFFECTIVE alternate as mention by Joshua Bloch in Effective Java (2nd ed, item no 3) is creation singleton using Java enum.
Lets see how simple is it
public enum MySingleton { INSTANCE; public void sayHello() { System.out.println("Hello World"); } public void sayBye() { System.out.println("Bye Bye"); } }
And how we call it
public class TestSingleton { public static void main(String[] args) { MySingleton.INSTANCE.sayHello(); MySingleton.INSTANCE.sayBye(); } }
Obviously the sayHello() and sayBye() is not thread safe( since we have not made them thread safe).
But as far as creation of singleton instance is concern ‘It is completely thread safe’. Also since enum is special type of java class and it can have methods and other variables. So we can add all other required stuff to the enum class and use where ever required. For example :
MySingleton singleton = MySingleton.INSTANCE; singleton.sayHello(); singleton.sayBye();
As we see here writing a singleton using enum is very simple and effective without worrying too much on concurrency and other stuff.