Singleton is an creational design pattern where a single instance is exist of a class at runtime .
Advantage:
If there raise such a situation where we want to restrict not to create more than one object ,just provide a mechanism to use that object then singleton is suitable process.
Ex:Database connection class could be singleton
How to write a singleton class?
steps 1. declare a static type instance to store the instance.
step 2.make the default constructor private .
step3.declare a static public method to return that static object.
below is the example,
Singleton: (Single threaded)
final public class Singleton {
private static Singleton INSTANCE = null;
private String value;
private Singleton(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static Singleton getInstance(String value) {
if (null == INSTANCE)
INSTANCE = new Singleton(value);
return INSTANCE;
}
}
MainApp:
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance("xyz");
System.out.println(singleton.getValue());
Singleton singleton2 = Singleton.getInstance("abc");
System.out.println(singleton.getValue());
}
The given example is working fine in with single threaded application . But what if it is in multithreaded application . lets see the example,
public static void main(String[] args) {
Thread foo = new Thread(() -> {
Singleton singleton1 = Singleton.getInstance("foo");
System.out.println(singleton1.getValue());
});
Thread bar = new Thread(() -> {
Singleton singleton2 = Singleton.getInstance("bar");
System.out.println(singleton2.getValue());
});
foo.start();
bar.start();
}
output:
foo
bar
It is showing wrong output because each thread is writing value to their own cache of OS. One thread doesn't know about the value of others.
So how to resolve it ?
Ans: Make the instance creational method synchronized.
let see the example -
public static Singleton getInstance(String value) {
Singleton result = INSTANCE;
if (null != result)
return result;
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton(value);
}
return INSTANCE;
}
}
We can introduce the synchronized block using Lock of that class. So that only one thread who first acquire that block can create the object . Others thread can not acquire the block . Whenever object is created others thread will always get that already created object . Because we assigned created object into the result variable.