Singleton is a design pattern that allows only one instance of a particular class. It can be used without creating an object of that specific type. In that respect, it has some similarities with static variables but there are some subtle differences that will be discussed soon.

Reasons to use

There are many reasons for why would we do it. Some of these are

  • If your requirement is to have one instance of a particular class e.g. single context for a particular app, a single management thread, database driver etc.
  • If you want to return only a single instance of a particular kind for a certain environment (You can make use of polymorphism and inheritance in singletons e.g. java.lang.Runtime returns an instance that is configured with respect to the particular JVM in which it is being called.)
Simple UML class diagram

Following is a simple class diagram of a singleton:


Singleton Design Pattern

Class Diagram of Singleton

Basic implementation

Following is an example implementation of a singleton class in Java:

Restricting multiple ‘new’ calls

The main problem with the above code is that it allows the client to create more instances (using ‘new’ operator) of the class itself, although the ‘ls’ variable is static.

To get rid of this problem we can make use of the following snippet:

Wrapper function

Now, the problem of having a direct access to an internal but public member of a class appears. We can easily resolve this issue by providing a function which can return the static instance. This way we can do pre-processing before returning the main instance. Here is how we will do it:

Memory consumption before instantiation

Above code is a pure singleton that will make sure that only one instance of the class is created. The main problem in the above code is that the instance will be created when the class is loaded in the Java Virtual Machine. This will waste some memory. What if we only want it to be created when some client calls it for the first time? We can make use of the following code:

Ok, this will ensure that we return only a fully qualified instance when it is called and null otherwise.

Multi-Threaded environments

This will not work in multi-threaded environments (e.g. in Android environment). If two threads are accessing it concurrently, then once first thread called getInstance method but it gets interrupted for some reason, then when the second thread calls it, then we will get an instance of our static variable. But, once the former thread wakes up a new instance is created again from that memory location. This way we would have two instances.

To avoid such a scenario, we can use the synchronized keyword. This way we will make each thread wait until another thread comes out of the getInstance method. So, no two threads will be in the method at the same time. This way we would have a performance hit. Here is an example of how to do it:

Double-check locking

You can also use a technique called ‘double-check locking’ which will help you manage your synchronization in a much more better way. Here is how to do it:

Problems due to Serialization, Cloning, Reflection, and multiple Class Loaders

Singleton pattern can still be circumvented. It is still possible to have multiple instances e.g. if the class is Serializable, Clonable, or if is used by the Reflection or if multiple class loaders are loaded it. To get rid of such problems you can make use of the following technique:

Benifits in regard to static variables

Following are some of the important benefits you get if you use Singletons rather than static variables:

  • Singleton can be garbage collected
  • Singleton follows Object Oriented Programming
  • Singletons are stored in Heap, whereas statics are stored in a stack
  • Singletons can be passed as objects
  • Singleton classes can be extended i.e. compliant with polymorphism (would private constructor allow us?)
  • Singleton classes can implement interfaces
  • Singletons can easily be serialized

We have to remember one more thing. It is that using statics or using singleton serves different purposes. You have to think carefully before using one of them, as to what you want to achieve.