Singleton pattern in java
Singleton design pattern allow creation of only single instance of class. It is one of the creational design pattern, mentioned in Design Patterns book. What we know at this point, first that this pattern related to creation of object, second only a single object of a class can be created.
Why we require this in first place. Imagine you are working on application that talks to the database. So, you require some kind of connection instance to talk to database. And there is a limit on how many connections you can create. Let us assume only one connection is allowed by database administrators for our application. But this connection instance is used by different places in our application.
With this requirement in mind, We know that usual way to get the instance of a class is
using new
keyword (like new MyConnectionClass
). But if we write that in our application, it will create
n
objects where n
is number of times the constructor is called using new
.
So, what is the solution of this problem, one straight forward way is to first stop the calling of new constructor
from outside of the class. That can be done by making the constructor private.
class MyConnectionClass {
private MyConnectionClass() {}
}
Now, we need some kind of method that returns the same instance every time it is called. So, how can we ensure that it
returns the same instance. We can do it by making a private
static
final
field in a class and returning
it from our public method. Look at the below code, to see what i am talking about.
class MyConnectionClass {
private static final MyConnectionClass instance = new MyConnectionClass();
private MyConnectionClass() {}
public getInstance() {
returns instance;
}
}
Above code example is the most basic example of singleton pattern but there are many variations of this pattern. I will
discuss them here. But First look at the line in above code that is
private static final MyConnectionClass instance = new MyConnectionClass();
Here as you can see, object of the class are created when this class are loaded by JVM. So, we can say that object are
eager initialized
. But if you want to initialize instance lazily, for example - to create object when the method is
first called, we write code that looks something like below code.
class MyConnectionClass {
private static MyConnectionClass instance;
private MyConnectionClass() {}
public getInstance() {
if (instance == null) {
instance = new MyConnectionClass();
}
returns instance;
}
}
Comparing this code with the above code, see we are no longer defining an instance as final
, and inside the
getInstance
method we are first comparing instance
reference with null
. If it is null we are calling the
constructor, otherwise returning instance as it is. If you are using this pattern in single threaded environment, it
is fine. But in multithreaded environment, this pattern can lead to race condition resulting in more than one instance
to be created.
At this point, I have given two examples, first eager loaded and second lazy loaded. But second one is not thread safe. Let's view the classification diagram.
![](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsingleton.a6a31b97.png&w=3840&q=75)
Even though, i have given the example of Basic Singleton and Lazy Singleton. In following sections, i will be giving the examples of all the patterns as given in classification diagram.
In this section
- Basic singleton
- Static block singleton
- Lazy singleton
- Synchronized method singleton
- Double locking synchronized singleton
- Inner static singleton
- Enum based singleton
Basic Singleton
It is the simplest singleton pattern with eager loading of instance.
public class BasicSingleton {
int value = 0;
private static final BasicSingleton INSTANCE = new BasicSingleton();
private BasicSingleton(){}
public static BasicSingleton getInstance() {
return INSTANCE;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
In above code example, I have taken a field value
. You can test the singleton of the class by first
creating an instance and setting some value to this field value
, say 5. Now, create another instance
(by calling getInstance() method) of the class. Now if you get the value of field value
, you will notice that
its value is 5 that we have set earlier. Or you can even print the hashcode of both the instances and compare them.
Static Block Singleton
Static block singleton is another way we can eager initialize instance. One benefit of using this pattern is that, if the creation of instance is complex or it can throw exception then using this pattern we can handle the exception in the static block itself. Look at the following code, and see our constructor is throwing the exception.
import java.io.File;
import java.io.IOException;
public class StaticBlockSingleton {
int value = 0;
private static StaticBlockSingleton instance = null;
static {
try {
instance = new StaticBlockSingleton();
} catch (IllegalArgumentException | IOException e) {
System.out.println("Failed to initialize singleton ");
}
}
private StaticBlockSingleton()
throws IllegalArgumentException, IOException {
System.out.println("Initializing singleton");
File.createTempFile(".", ".");
}
public static StaticBlockSingleton getInstance() {
return instance;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Lazy Singleton
As the name suggest, it is lazy way to initialize the instance but the major drawback of this pattern is that it is not thread safe.
public class LazySingleton {
int value = 0;
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Synchronized method singleton
It is improvement over lazy singleton example. It is done by making the getInstance synchronized. This approach will
make our singleton class thread safe but writing synchronized
in front of method name is not a good approach as it will
lock the object/class.
In our case, we are writing synchronized
in front of static method. So, the thread calling our method
acquire the lock at class level which block any other thread from accessing other synchronized
static method
while one thread is inside our synchronized static method.
Here is the example of this approach, in later section I will discuss the other approaches of synchronization.
public class SynchronizedMethodSingleton {
int value = 0;
private static SynchronizedMethodSingleton instance;
private SynchronizedMethodSingleton() {}
public static synchronized SynchronizedMethodSingleton getInstance() {
if (instance == null) {
instance = new SynchronizedMethodSingleton();
}
return instance;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Double locking synchronized singleton
This approach is an improvement over Synchronized method singleton. Here we are only synchronising the critical
section of getInstance method and which is if (instance == null)
. Let me give the example without double locking.
public static synchronized SingleLockingSingleton getInstance() {
synchronized (SingleLockingSingleton.class) {
if (instance == null) {
instance = new SingleLockingSingleton();
}
}
return instance;
}
This code uses the synchronized
block but still it is not performant because every time getInstance
method is
called, the synchronized block is executed irrespective of instance is null or not. So now, I will present you the
example to Double locking synchronized singleton.
public class DoubleLockingSingleton {
int value = 0;
private static volatile DoubleLockingSingleton instance;
private DoubleLockingSingleton() {}
public static DoubleLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleLockingSingleton.class) {
if (instance == null) {
instance = new DoubleLockingSingleton();
}
}
}
return instance;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Using double locking we ensure that synchronized block is executed only if the instance is null and not other times.
There is one other point I want you to consider which is volatile
declaration of instance. It is important to
make the field volatile as helps in visibility.
To understand, let's imagine we declared the instance field without volatile. So, without it,
jvm can rearrange instructions. Look at this line instance = new DoubleLockingSingleton();
.
Without volatile
it is possible that instance
variable is marked as not null
but the constructor DoubleLockingSingleton
is still executing (left hand side executed before right hand side).
At this moment instance does not point to fully constructed instance and when another thread access it. Our application
might crash. It is also important to note that this approach with volatile
only works with java 4 and above.
Inner static singleton
This approach uses static inner class and its is both lazy loaded and thread safe. Also code is pretty simple. Let's look at the example.
public class InnerStaticSingleton {
private InnerStaticSingleton(){}
private static class Impl {
private static final InnerStaticSingleton instance =
new InnerStaticSingleton();
}
public InnerStaticSingleton getInstance() {
return Impl.instance;
}
}
Enum based singleton
We can also use enum to create singleton as only finite amount of instances can be created with enum. With the patterns defined in above cases the singleton can be broken by reflection or serialization. But enum based singleton is protected by these issues (there is a caveat with serialization of enum, as fields are not serialized in enum).
public enum EnumBasedSingleton {
INSTANCE;
private int value;
EnumBasedSingleton() {
value = 10;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
We also have to consider that enum cannot be inherited. So, if we want to do inheritance we cannot use this pattern.
Summary
In this article, I have shown the patterns of creating singleton, such that only one instance of the class is created. I have classified these patterns on the basis of eager/lazy loaded and thread safety.
If you liked this article, consider following me on X where I will be announcing for new posts.