Singleton Pattern is one of the famous design patterns from the Gang of Four. Even though nowadays it is considered as an anti-pattern, it has served us well in the past. In the Singleton pattern, a class has just one instance throughout its lifetime and that instance is shared between multiple clients. Singleton class has two responsibilities, first to ensure that only instance of the class gets created and second, to provide a method getInstance() so that everyone can get access to that single instance, I mean, global access.
One of the issues, faced by the Singleton design pattern in the multi-threading program is to ensure that just one instance of the class gets created, even if multiple clients called the getInstance() method same time.
Many programmers solved this problem by making the whole getInstance() method synchronized, which results in poor performance because every time a thread enters a synchronization method, it acquires the lock and while it's been inside the method, no other thread is allowed to enter, even if they are not creating an instance and just accessing already created instance.
How do you solve this problem? Well, you can use Double-checked locking idiom, which you learn in this article. Btw, if you are curious about why Singleton is considered an anti-pattern, I highly recommend the book Games Programming Patterns by Robert Nystrom, though examples are in C++, it's one of the most readable books on design patterns, you won't feel bored or cheated.
How do you solve this problem? Well, you can use Double-checked locking idiom, which you learn in this article. Btw, if you are curious about why Singleton is considered an anti-pattern, I highly recommend the book Games Programming Patterns by Robert Nystrom, though examples are in C++, it's one of the most readable books on design patterns, you won't feel bored or cheated.
Thread Safe Singleton using Double Checked Locking Idiom
Double checked locking idiom solves this problem by allowing you to eat your cake and have it as well, it ensures synchronization is used only when an instance of Singleton is created when the getInstance() method is called first time and all other times, the same instance is returned without any synchronization overhead.As the name suggests, it's double-checked, which means it checked two times whether _instnace (the singleton instance) is initialized or not, one without synchronization and the other with synchronization.
This double-check ensures that locking is only used when an instance is null i.e. when the first time someone calls getInstance(), all subsequent calls will see _instnace not null hence they will not enter into the synchronization block.
Here is the code of thread-safe singleton pattern using double-checked locking idiom:
Here is the code of thread-safe singleton pattern using double-checked locking idiom:
/** * Thread Safe Singleton in Java using Double checked locking. * @author WINDOWS 8 * */ public class Singleton { private static volatile Singleton _instance; /** * Double checked locking code on Singleton * @return Singelton instance */ public static Singleton getInstance() { if (_instance == null) { synchronized (Singleton.class) { if (_instance == null) { _instance = new Singleton(); } } } return _instance; } }
How Double Checked Locking Idiom Works?
To illustrate the point, how this idiom prevents from two instances being created when two thread simultaneously calls the getInstance() method, let's see the theory. Suppose, thread T1 calls getInstance() very the first time and sees that _instance is null then it will go inside synchronization block and that point of time it paused.Now, thread T2 calls getInstance() and it will also see _instance variable null, but it cannot go inside synchronization block because the lock is held by Thread T1, which is inside the synchronization block. Now, thread T1 wake up and creates a new instance of singleton and come out of synchronized block.
After this when thread T2 goes inside synchronized block, it again checks whether _instance is null and this time check fails because _instnace is no more null. So thread T2 comes out of the synchronized block without creating another instance. Further calls to this method return from the first check only.
By the way, double-checked locking idiom was broken before Java 5. It was possible for a thread to see a half initialized instance which will fail the first null check, resulting in returning a half-initialized Singleton.
By the way, double-checked locking idiom was broken before Java 5. It was possible for a thread to see a half initialized instance which will fail the first null check, resulting in returning a half-initialized Singleton.
That's why it's absolutely critical to make _instnace a volatile variable. The Java memory model updates and happens-before makes double-checked locking works again.
That's all about how to create thread-safe Singleton in Java, but this is not the only way to create the thread-safe singleton. You can use Enum as Singleton then Java itself will guarantee that only one instance will be created even in the case of multiple threads trying to access it at the same time.
That's all about how to create thread-safe Singleton in Java, but this is not the only way to create the thread-safe singleton. You can use Enum as Singleton then Java itself will guarantee that only one instance will be created even in the case of multiple threads trying to access it at the same time.
Alternatively, you can also eagerly initialized the Singleton, in that case, it would be initialized on static initializer block at the time of class loading in a thread-safe manner. If you decide to use double-checked locking idiom to make Singleton creation thread-safe, don't forget the volatile modifier.
Further Reading
If you want to learn more about safe publication techniques in concurrency and other concurrency gotchas, read Java Concurrency in Practice by Brian Goetz, one of the most respected books on Java concurrency.
And, if you want to read more about design patterns, particularly about Singleton patterns with examples from game development, try Game design patterns by Robert Nystrom, one of the interesting books I read this year.
Further Reading
If you want to learn more about safe publication techniques in concurrency and other concurrency gotchas, read Java Concurrency in Practice by Brian Goetz, one of the most respected books on Java concurrency.
And, if you want to read more about design patterns, particularly about Singleton patterns with examples from game development, try Game design patterns by Robert Nystrom, one of the interesting books I read this year.
Prefer using enum as singleton. Thread safe, serialization ready out of the box, less code, easy to read...
ReplyDeleteHi Javin - your class in not final so can be extended and modified.Also what about reflection breaking this singleton?
ReplyDeleteHi Maddy, yes reflection is breaking this Singleton but seems to being a Singleton class, a class need not to be final as the constructor of the class is marked as private. So when one will try to create the subclass, one will get the compilation error.
ReplyDeleteHello Maddy and Vishu, I think class final is optional but good because when you have private constructor you cannot create a subsclass except an inner subclass. Yes, Reflection can break Singleton.
DeleteCan you post a working java code of Threads accessing the Double check locking singleton pattern
DeleteHi Vishu, preventing from reflection you can write a condition to check first instance is null or not in private constructor and throw RunTimeException. By doing this you can make singleton in reflection also.
Delete