As a programmer you should have come across many design patterns, in this blog entry I would like to spend some time on Singleton Design pattern. Before, further discussion on Singleton pattern, let us try understanding what is Design Pattern, and why do we need to learn about these patterns.
A Design pattern, is a specification defined to solve a particular problem. In our day to day programming we will be trying to solve several problems, design patterns are those solutions which are adopted by many developers around the globe to solve those specific problems you face today. Now its time for you to adopt some of those in your code, instead of fighting out your own solution for the problems you have on your table.
Below are few Design patterns, which were mostly adopted by many developers across the globe, in their day to day development.
- Factory Object
- DAO pattern
Let us try to see the problem statements, that can be solved using the Singleton pattern and then we can dig more deeper on to what is a Singleton and what ways we can define singletons.
Problem Statement 1: My JVM goes OOM, because an object with heavy foot print is created several times, by several threads.
Problem Statement 2: I want a shared object across several threads during manipulation, without passing the references of that object.
Problem Statement 3: I want to define a utility class, but don’t want to create all the methods of that utility class as static.
If you, are stuck with any of the problem statements given above, then its time for you to implement a Singleton pattern for those objects. Now, that we know when to use a Singleton pattern, lets see what are its qualities, and what it offers for the developers.
- Singleton objects can be instantiated only once
- At any point of time there will be one and only one object in the JVM
- All the threads will share the same object.
Now that, you have seen what all situations we can use Singleton, and what are the properties of a Singleton, let me show you how can we implement a Singleton pattern. A Singleton can be implemented using several techniques, I will try to cover some of those in this post.
1. Eager Instantiation
2. Lazy Instantiation
b. Double Checked Locking
c. Double Checked locking using volatile keyword
c. Using Inner Class
3. Using Enums as Singletons
Each of the above techniques with implementation details and examples, are explained hereunder, for giving you basic view of each of the technique.
Eager instantiation means, the object is initialized when the class is loaded, even before there is any actual invocation for getting a reference to that object. This method is not advisable, as you will be creating an object, even before it is needed for your application. If you object loaded this way, is a heavyweight object then you will be wasting a lot of Heap memory.
Lazy instantiation means, the object is initialized when the application requires it, instead of creating at the time the Class is loaded on to the JVM. Lazy instantiation can be done in variety of ways, each having subtle problems which I will be explaining shortly.
Locking: In this method we will make the get Instance method synchronized, this will acquire a lock on the Class type, and any threads that want to access the methods of this class will be kept on waiting and the performance degrades at a high degree.
Double Checked Locking: In this method we will check whether the object is initialized before acquiring the lock, and again check whether any thread has completed the creation of the object after acquiring the lock, and then create an object.
In this approach, there is a limited possibility of error, that is when a Thread acquires a lock and a constructor is being called. Even before the completion of the constructor, another thread might request for getInstance and see that foo is not “null”, and hence returns a partially initialized object. These sort of partially initialized objects can break the system, and will be very hard to debug.
Double Checked Locking Using volatile: In this method we will be implementing the same Double Checked Locking pattern, while adding a keyword called volatile(Introduced in JDK 1.5) to the object variable. Volatile keyword makes sure that there is no ThreadLocal copy of this variable, and hence will always reference to the same object though it is accessed by multiple threads.
Using Inner Class: In this method we use a Singleton Helper inner class to lazily load the object, which is guaranteed to have a single reference of it across all the threads.
I prefer, creating the Singleton objects using this Inner Class methods, since there is no need to explicitly handle the synchronization issues, and the job of creating and making sure that only instance of the object to the compiler.
Using Enums as Singletons:
Using Enum Singletons, is increasing in todays programming, as they are more Thread-safe, and again the job of creating an object is handled by the compiler itself. While we use the Enum’s, to mark types in java having some constants usage of enum as a singleton might not sound perfect for many reasons.
Hope this article, has given some insights to you on Singleton pattern, and was a good read. The concepts, and examples I have given in the justification are based on my opinions and experience. I would really love to hear any comments or suggestions, so please give your feedback in the comments section.
- To know more about using Enums as Singletons, go through this link.
- More about volatile keyword can be found here.