Java Singleton Design Pattern
Its one of the simplest design pattern in Java.
If any one asks me which design pattern you are good then I would proudly say Singleton.
But when they ask in depth concept of singleton then I get stumped.
Is it really singleton is that much difficult ?
Really not but it has many scenarios that we need to understand (especially beginners).
Definition :
There should be only one instance allowed for the class in all the situation and we should provide global point of access to that instance.
Definition is as easy as 1,2,3 and A,B,C,D.
Lets see how can we implement Singleton Class.
How can we ensure object should be only one all the time ?
Hint : put object creation logic in only one place and don’t allow users to execute this logic every time they try to but allow only once.
Object creation logic -> what it is
How we create object in Java ?
Yes using constructor , and we should not allow users to access constructor and execute it every time they try to.
But we should do it one time to get one object at least.
So how can we ensure constructor is accessible and executable only once?
- Prevent constructor access outside the class so that no outsiders can be able to create an instance.
How to make it -> how to prevent method access outside class ?
Simple, make method as private right, similarly make constructor as private. - Prevent constructor execution inside the class more than once.
How to make it -> this has many ways to implement, lets see it with example.
If above 2 conditions are satisfied then we will have always one object for our class. And that class is called as Singleton as it produces single object all the time we request.
No much theory, we will start implementing it now.
Many Ways of creating singleton object are available:
Approach 1
- Eager initialization or initialize before use
package com.kb.singleton; public class EagerSingletonClass { private static volatile EagerSingletonClass singletonInstance = new EagerSingletonClass(); //making constructor as private to prevent access to outsiders private EagerSingletonClass() { } public static EagerSingletonClass getInstance(){ return singletonInstance; } }
The instance of EagerSingletonClass is created at the startup of the class. Since it’s a static, it gets loaded and created during loading of the EagerSingletonClass.
- Junit test class for the above class to test singleton.
package com.kb.singleton; import static org.junit.Assert.*; import org.junit.Test; public class EagerSingletonClassTest { @Test public void testSingleton() { EagerSingletonClass instance1 = EagerSingletonClass.getInstance(); EagerSingletonClass instance2 = EagerSingletonClass.getInstance(); System.out.println("checking singleton objects equality"); assertEquals(true, instance1==instance2); } }
Advantage :
This strategy creates the object during the loading of the class and hence its faster and safer from multithreading scenario. Only thing we have to make instance as volatile for handling multi threading scenario.
Disadvantage :
This strategy creates the instance during class loading itself, hence if we don’t use it then it’s a waste of whole time and memory taken to create the instance. So better to go for a strategy to create an instance as and when we require it.
When to use above strategy?
Whenever we are 100% sure that object is definitely used in our application.
OR
When the object is not heavy also its ok we can manage speed and memory.
Approach 2
- Lazy initialization or initialize as and when we need
Instead of creating an object at the startup, it’s good to create an object as and when it is required. So let’s see how can we do that:
package com.kb.singleton; public class LazySingleton { private static volatile LazySingleton singletonInstance = null; //making constructor as private to prevent access to outsiders private LazySingleton() { } public static LazySingleton getInstance(){ if(singletonInstance==null){ synchronized (LazySingleton.class) { singletonInstance = new LazySingleton(); } } return singletonInstance; } }
In the above program, we have created an object only when there is a request through getInstance() method.
Here during the first invocation of getInstance(), the object ‘singletonInstance’ will be null and it executes the if condition block as it becomes true and creates an object.
Then subsequent calls to getInstance() method will return the same object .
But if we look at the multithreading scenario , problem comes when below context comes 2 threads t1 and t2 calls getInstance() method and thread t1 executes if(singletonInstance==null) and finds singletonInstance as null so it enters the synchronized block to create an object.
But before it executes the object creation logic if thread t2 executes if(singletonInstance==null) then it will also find singletonInstance as null so it will also try to enter synchronized block but it will not have a lock as the first thread t1 already entered .
So thread t2 waits for the thread t1 to complete the execution of synchronized block.
Hence thread t1 executes and creates the object . now thread t2 also enters the synchronized block as it was waiting for the synchronized block and creates the object once again.
So two objects are created by 2 threads. So fails to achieve singleton.
Solution to the above problem is Double Checked Locking.
It says re check the instance variable again inside the synchronized block before we execute the logic of object creation inside synchronized block.
So this way we can avoid the creation of object more than once by multiple threads.
How ?
Thread t1 checks the condition if(singletonInstance==null) and it is true for first time so it enters synchronized block and there again it checks the condition if(singletonInstance==null) and this is also true so creates the object.
Now thread t2 enters the method getInstance() and assume it has executed if(singletonInstance==null) condition before the thread t1 executes the object creation logic then t2 also waits to enter the synchronized block.
After thread t1 comes out of synchronized block thread t2 enters the same block , but we have again the if condition there if(singletonInstance==null) but thread t1 already created an object, it makes the condition to be false and stop the execution further and returns the same instance .
Lets see how it can be done in code:
package com.kb.singleton; public class LazySingletonDoubleLockCheck { private static volatile LazySingletonDoubleLockCheck singletonInstance = null; //making constructor as private to prevent access to outsiders private LazySingletonDoubleLockCheck() { } public static LazySingletonDoubleLockCheck getInstance(){ if(singletonInstance==null){ synchronized (LazySingleton.class) { if(singletonInstance ==null){ singletonInstance = new LazySingletonDoubleLockCheck(); } } } return singletonInstance; } }
Lets do the unit testing
package com.kb.singleton; import static org.junit.Assert.*; import org.junit.Test; public class LazySingletonDoubleLockCheckTest { @Test public void testSingleton() { LazySingletonDoubleLockCheck instance1 = LazySingletonDoubleLockCheck.getInstance(); LazySingletonDoubleLockCheck instance2 = LazySingletonDoubleLockCheck.getInstance(); System.out.println("checking singleton objects equality"); assertEquals(true, instance1==instance2); //fail("Not yet implemented"); } }
The above implementation is the best advisable solution for singleton pattern which is best suitable for all scenarios like single threaded, multithreaded.
Approach 3
- Singleton using Inner class
Let’s see the below code of creating object using inner class:
package com.kb.singleton; public class SingletonUsingInnerClass { private SingletonUsingInnerClass() { } private static class LazySingleton{ private static final SingletonUsingInnerClass SINGLETONINSTANCE = new SingletonUsingInnerClass(); } public static SingletonUsingInnerClass getInstance(){ return LazySingleton.SINGLETONINSTANCE; } }
Unit test code
package com.kb.singleton; import static org.junit.Assert.*; import org.junit.Test; public class SingletonUsingInnerClassTest { @Test public void testSingleton() { SingletonUsingInnerClass instance1 = SingletonUsingInnerClass.getInstance(); SingletonUsingInnerClass instance2 = SingletonUsingInnerClass.getInstance(); System.out.println("checking singleton objects equality"); assertEquals(true, instance1==instance2); } }
The above approach of creating object using inner class is one of the best approach to create singleton object.
Here unless and until someone tries to access the static reference variable of LazySingleton static inner class, the object will not be created.
So this will also ensure the creation of object as and when it is required. And it is very simple to implement. It is also safe from multi-threading.
Approach 4
- Singleton with serialization and de serialization
Now assume our application is distributed and we serialize our singleton object and write it to file. Later we read it by de serializing the singleton object. De serializing the object always creates a new object with the state available inside the file. If we do any state change after writing to a file and then try to de serialize the object , we will get original object not new state object. So we got 2 objects in this process.
Lets try to understand this problem by program:
First thing -> make the singleton class serializable to serialize and deserialize this class’s object.
Second thing -> write the object to file(serialization)
Third thing -> change the object state
Fourth thing -> de serialize the object
Our singleton class is as below:
package com.kb.singleton; import java.io.Serializable; public class SingletonSerializeAndDesrialize implements Serializable { private int x=100; private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize(); private SingletonSerializeAndDesrialize() { } public static SingletonSerializeAndDesrialize getInstance() { return singletonInstance; } public int getX() { return x; } public void setX(int x) { this.x = x; } }
Serialize our object then do some change in the state and then de serialize it.
package com.kb.singleton; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; public class SerializeAndDeserializeTest { static SingletonSerializeAndDesrialize instanceOne = SingletonSerializeAndDesrialize.getInstance(); public static void main(String[] args) { try { // Serialize to a file ObjectOutput out = new ObjectOutputStream(new FileOutputStream( "filename.ser")); out.writeObject(instanceOne); out.close(); instanceOne.setX(200); // Serialize to a file ObjectInput in = new ObjectInputStream(new FileInputStream( "filename.ser")); SingletonSerializeAndDesrialize instanceTwo = (SingletonSerializeAndDesrialize) in.readObject(); in.close(); System.out.println(instanceOne.getX()); System.out.println(instanceTwo.getX()); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
Output:
200
100
It clearly says we have 2 distinct objects even though its singleton. This is happening because de-serialization creates new instance with the state available in the file.
How to overcome this problem ? Means how to prevent creating new instance during de serialization?
Solution is very simple – implement below method in your singleton class:
Access_modifier Object readResolve() throws ObjectStreamException{ }
Example:
Public Object readResolve() throws ObjectStreamException{ return modifiedInstance; }
Apply this to above singleton class, then complete singleton class is as below:
package com.kb.singleton; import java.io.ObjectStreamException; import java.io.Serializable; public class SingletonSerializeAndDesrialize implements Serializable { private int x=100; private static volatile SingletonSerializeAndDesrialize singletonInstance = new SingletonSerializeAndDesrialize(); private SingletonSerializeAndDesrialize() { System.out.println("inside constructor"); } public static SingletonSerializeAndDesrialize getInstance() { return singletonInstance; } public int getX() { return x; } public void setX(int x) { this.x = x; } public Object readResolve() throws ObjectStreamException{ return singletonInstance; } }
Now run our above serialize and deserialize classes to check the output for both the instances.
Output:
200
200
This is because, during de serialization it calls readResolve() method and there we are returning the existing instance which prevents creating new instance and ensures singleton object.
- Careful with Serial version id
Whenever the class structure gets change after we serialize and before we de serialize it. Then during de serialization process , it finds an incompatible class and hence throws an exception: java.io.InvalidClassException: SingletonClass; local class incompatible: stream classdesc serialVersionUID = 5026910492258526905, local class serialVersionUID = 3597984220566440782
So to avoid this exception we have to use serial version id to the serializable class always. And its syntax is as below:
private static final long serialVersionUID = 1L;
So finally by covering all the above scenario, the best possible solution of singleton class is as below and i recommend to use this one always:
package com.kb.singleton; import java.io.Serializable; public class FinalSingleton implements Serializable{ private static final long serialVersionUID = 1L; private FinalSingleton() { } private static class LazyLoadFinalSingleton{ private static final FinalSingleton SINGLETONINSTANCE = new FinalSingleton(); } public static FinalSingleton getInstance(){ return LazyLoadFinalSingleton.SINGLETONINSTANCE; } private Object readResolve() { return getInstance(); } }
Reference: | Java Singleton Design Pattern from our JCG partner Karibasappa GC at the Java Guide Simple way to learn java blog. |
The best possible solution is the enum singleton.
public enum EnumSingleton{
INSTANCE;
}
It is extremely simple, threadsafe and protected during deserialization. It is also easy to extend to multiton.
I agree simple approach of using singleton is Enum but i suggest to use inner class strategy for singleton. Reasons 1: enum does not allow lazy initialization 2: By default enum’s super class is Enum always. and how we can make enum to extend our application class rather than getting un wanted super class ? but the same we can achieve easily in our singleton class using extends keyword. 3: Enums contains some static methods public static Foo2[] values() { … } public static Foo2 valueOf(String name) { … } public static <T extends Enum> T valueOf(Class enumType, String name)… Read more »
Hi, I agree with Zoltan comment, but I think that singleton pattern is almost always abused, to the point that IMHO it is an anti-pattern actually.
It’s common opinion that a single instance of any classes should be enforced by application, not by a “sealed” class; with frameworks like Spring, Guice and the like, this is trivial to achieve.
You must have a really good reason to implement a singleton in 2014; HibernateSessionFactory, which is a class whose instantiation is among the most expensive I ever came across, is not a singleton, why should your classes be such?
I agree with you and what i could say is
A singleton must be used when managing access to a resource which is shared by the entire application,
and it would be destructive to potentially have multiple instances of the same class.
Example : Logger class, some config load common to application.
As I said, this kind of behaviour is to be obtained by means of an external framework or by other means; it is trivial (and in fact it is the default scope) to have a single instance across the entire application in Spring, for example.(1) Hard wiring this behaviour into a class is seldom a good idea, a static factory (like slf4j’s LoggerFactory for example) is a much better approach. (2) There will always be a case where someone will need a second instance and cases shere someone will need a slightly different implementation (for example for unit tests). Another… Read more »
Agreed.
but
singleton classes should be chosen whenever we need to have state of an object and that state also needs to be same across the application all the time.
same can be achieved using factory but factory literally used when we have group of objects and return only one out of it based on the requirement.
Any thoughts on 1 and 3? Don’t they fully satisfy this requirement without the use of singletons? I agree that slf4j wasn’t the best example, but you can make a factory always return the same instance if that’s what you need, but again it’s not something that you should enforce on the class itself in any scenario I can think of.
Are you also aware that the approaches you suggested only guarantee one instance per classloader hierarchy, not just one per vm?
This articles explains very well why singleton is bad in most cases:
http://www.ibm.com/developerworks/webservices/library/co-single/index.html
I absolutely agree, actually this is an anti-pattern. The best use of this knowledge is at interviews:)
I didn’t cover that part of clone and one per VM concepts for singleton(like class loader concepts).
i do agree there are few more scenarios apart from what i covered. will add it during my free time.
there are couple of drawbacks with factory patterns for singleton object, you can explore on them.
ultimately what i could suggest is, use singleton only when the situation demands. and use it very carefully.
Why do you use “volatile” in Approach 1 and 2? Thanks.
Hi, its really a good question.. Basically in Java volatile solves one issue that is visibility issue . If you are writing to one variable that is declared volatile then the value will be visible to other thread immediately. if we write to a non volatile variable in one thread it is not guaranteed to be visible to other thread , so if we use volatile it writes to direct memory and is visible to all other threads. Volatile variable: : If two Threads(example t1 and t2) are accessing the same object and updating a variable which is declared as… Read more »
Hello,
I don’t agree with you for approach 1.
The singleton is create when the class is INITIALIZED, not LOADED.
This makes a big difference and make it the best approach from all perspectives.
See: http://javarevisited.blogspot.fr/2012/07/when-class-loading-initialization-java-example.html
Regards,
yes it should be during class initialization that is when someone tries to access that static field , that time only its going to be initialized…
but in my approach, loading will not happen before initialization, no special code is written to eagerly load the class..i think loading happens when we tries to initialize but before initialization.
do you know any way in Java , how we can lazy load the class and how we can eager load the class ?
I agree with karibasappa that loading always happens during initialization i.e. just before initialization. Many Publishers and authors use term lazy loading and eager loading which is absolutely incorrect. It should be lazy initialization or eager initialization.
Good usages, but clone part is missing. Can restrict cloning of this Singleton obj.