Answer to why we need double check locking in singleton class in Java with thread program example.
Let’s understand first what does the double checking means?
Consider the method getInstance() of below singleton class. You will see that there are two if conditions to check if the singleton class object is null. So, question is, if without having first if condition check the program can work fine, then why to use this?
class MultithreadedSingleton {
private static MultithreadedSingleton single;
private MultithreadedSingleton() {
}
public static MultithreadedSingleton getInstance() {
if (single == null) {
synchronized (MultithreadedSingleton.class) {
if (single == null) {
single = new MultithreadedSingleton();
}
}
}
return single;
}
}
Before answer to this interview questions, let’s have a complete example of threads and singleton class for double checking (2 if conditions to check if object is null) in java.
In this example, we have a singleton class in which we have used double check condition to create a unique object of the singleton class.
We have created five threads and they will try to enter critical section to create object of the singleton class.
Double checked locking in singleton java example
/*
* Singleton class
*/
class MultithreadedSingleton {
private static MultithreadedSingleton single;
private MultithreadedSingleton() {
}
public static MultithreadedSingleton getInstance() {
if (single == null) {
synchronized (MultithreadedSingleton.class) {
if (single == null) {
single = new MultithreadedSingleton();
}
}
}
return single;
}
}
/* Create a runnable task */
final class Task implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(
Thread.currentThread().getName() + " : " +
MultithreadedSingleton.getInstance().hashCode());
}
}
}
/*-----------------------------------------------------------
* Test singleton class
* */
public class TestSingleton {
public static void main(String[] args) {
Task t = new Task();
Task t2 = new Task();
Task t3 = new Task();
/* Create threads and assigne some task */
Thread tt = new Thread(t);
Thread tt2 = new Thread(t2);
Thread tt3 = new Thread(t3);
Thread tt4 = new Thread(t);
Thread tt5 = new Thread(t);
/* Start all threads */
tt.start();
tt2.start();
tt3.start();
tt4.start();
tt5.start();
}
}
Answer
Have double check to avoid performance issue.
Repeated Locking and unlocking make the program slow. For smaller number of threads, you will not notice, but consider thousands of threads then it is noticed.
In the above example, if you don’t have first check, then every time a thread come, lock will be performed. If thousands of threads…thousands of time lock will be performed.
If you have double check…only one-time lock will be performed.