Singleton Design Pattern
In Design Pattern article, we have seen different types of design patterns. In this article, we will understand one of the simplest Creational Design Pattern i.e. Singleton Design Pattern.
What is the purpose of Singleton?
The purpose of the singleton class is to control object creation, limiting the number of objects to only one. The singleton allows only one entry point to create the new instance of the class.
Since there is only one Singleton instance, any instance fields of a Singleton will instantiate only once per class, just like static fields. Singletons are often useful where we have to control the resources, such as database connections or sockets.
Singleton design pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine.
Approaches for writing Singleton Class
It seems to be a very simple design pattern but when it comes to implementation, it comes with a lot of implementation concerns.
The implementation of Singleton pattern has always been a controversial topic among developers.
There are many ways using which we can create singleton class. We have divided all of these approaches into 5 main categories. In this article, we will learn to implement Basic Singleton Design Pattern.
Why there are so many approaches? Why can't we have only one approach? Well, every approach has its pros and cons. You can choose best suitable approach based on the requirement of your application.
Eager Initialization
What are the essential points that you should consider while writing Singleton class?
- We want to take control over creation of the instances, so we will provide only private constructor. (Also read What is the use of private constructor in java?)
-
If nobody can explicitly create object of our class (as there is no public constructor), then who will create the instance? Of course, we need to create one instance. So we will create one instance and store it in private static variable named as
instance
. -
To access this private static variable, we will provide one public static accessor method
getInstance()
.
Java Program Implementation
class EagerInitializedSingleton { // Private static instance is created at the time of class loading private static EagerInitializedSingleton instance = new EagerInitializedSingleton(); // Constructor made private so that no new instance can be created private EagerInitializedSingleton() { } // Static method to return the instance to the client public static EagerInitializedSingleton getInstance() { return instance; } }
Download Complete Java Program »
Why this approach is known as Eager Initialization?
If you notice, initialization of the instance is done at the time of class loading. It will not wait for client to call getInstance() method. In other words, it will eagerly initialize the object.
What if client will never call getInstance() method?
instance will still get created and will remain in the Heap Memory which is waste of memory. This is the disadvantage of the eager initialization. This problem will be resolved using Lazy Initialization Approach.
What if some exception occurs while creating an object i.e. inside constructor?
We can write try catch block inside constructor. Another way to solve this problem is by using static block Initialization approach.
Static block initialization
Static block initialization implementation is similar to eager initialization, except that instance of class is created in the static block that provides option for exception handling. Below is the implementation:
public class StaticBlockSingleton { private static StaticBlockSingleton instance; private StaticBlockSingleton() { } static { try { instance = new StaticBlockSingleton(); } catch (Exception e) { throw new RuntimeException("Exception occured in creating instance"); } } public static StaticBlockSingleton getInstance() { return instance; } }
Download Complete Java Program »
Lazy Initialization
In practice, one should avoid using Eager Initialization and static initializer approach as in most of the cases the Singleton design pattern is used for creating heavy resources e.g. SessionFactory. It is preferred to initialize instance when clients asked for it i.e. when client calls getInstance()
method. How do we achieve this in code?
Lets tweak the implementation a bit to convert eager initialization code to lazy initialization. We will create new instance when client will call getInstance() method. Also we will check null condition before creating new instance to ensure that it has not already created.
public class LazzyInitializedSingleton { private static LazzyInitializedSingleton instance; private LazzyInitializedSingleton() { } // Lazy initialization is done when client first time request for the instance public static LazzyInitializedSingleton getInstance() { if (instance == null) { instance = new LazzyInitializedSingleton(); } return instance; } }
Download Complete Java Program »
Lazy Initialization implementation will work when the given environment is single threaded. However in multithreaded environment, above code may create more than one instances. For example,
-
Assume that two threads T1 and T2 are calling
getInstance()
method concurrently. - Thread T1 has checked the null condition on line 11 and entered inside if block as no instance has been created yet.
- T1 is inside the if condition, but it has not created instance yet. At the same time another thread T2 reaches to the null condition on line 11. As instance is still null, T2 also enters the if condition.
- Now both threads will create instance on line 12 which will break the singleton design pattern.
Here is the graphical representation for the same :
Thread Safe Lazy Intialization Singleton Pattern
If you notice the code in First two approaches i.e. Eager Initialization and Static block Initialization, then you can see that we are just returning the instance variable in getInstance() method. Process of creating instance happens eagerly at the time of class loading. Hence, we can conclude that both of these approaches are thread-safe, as there is no critical section inside getInstance()
method. Only drawback is eager initialization.
On the other hand, if we want to initialize object lazily, then we need to handle thread-safety explicitly using synchronized
keyword.
Howerver, There are many ways to implement Lazy Initialization Singleton Design Pattern in multithreaded environment like Synchronizing getInstance()
method, Double check locking mechanism and Bill Pugh Singleton Implementation Using Inner Class. We have dedicated entire article on thread safe singleteon design pattern as it will require detailed discussion.
Next Article in the series of Singleton Design Pattern : Singleton Design Pattern using Double Checked Locking
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Authors
Tags: Creational Design Patterns, Design Patterns, Singleton, Singleton Design Pattern
Comments and Queries
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:<pre><code class="java"> String foo = "bar"; </code></pre>For more information on supported HTML tags in disqus comment, click here.