Introduction
Why do we even need a singleton pattern? Consider a situation where you only want to create one instance of the class. For example, let’s say you’re calling an API in your project, as every API’s first step is to authenticate the client. After successful authentication, the server generates a session, which is alive for some time. Imagine for every single request you're creating a session, which is wrong at so many levels. You should only create a session once at use that session for all other requests (for example, Facebook's login to logout is one session). This is where we should use the singleton pattern.
- namespace SingletonPattern
- {
-
-
-
- class SingletonExample
- {
-
-
-
- private static SingletonExample obj;
-
-
-
-
- public SingletonExample()
- {
-
- }
-
-
-
-
-
- public static SingletonExample Initialise()
- {
- if(obj == null)
- {
- obj = new SingletonExample();
- }
- return obj;
- }
- }
- }
As you see in the above code we have static Initialise() method, so whenever your project calls this method for the first time, it creates a new object then after that it will just return the same instance.
There's a problem with the above code, as it's not thread-safe. It creates an instance for every thread that makes a request.
It's ok, no need to panic, as we have a solution for such cases. We have 2 keywords to help us out:
Volatile and Synchronised
Volatile (in brief):
In a multiThreaded scenario, one Thread which has a processor can cache some resource (properties/variables) out of your class in its cache memory for faster processing and where the other Thread holding the same old values resource which is on RAM. Here we have a mismatch issue, so in order to avoid that we use volatile. It makes sure cache data is updated on RAM and vice-versa.
Synchronised (in brief):
Synchronization allows only one thread to access the resource at a time. No other thread can get access to that resource until the assigned thread finishes its task. Threads execute asynchronously. Synchronization helps us by making threads synchronized.
We can use a locking mechanism to make it thread-safe.
C# Implementation (unsynchronized in C#, but we have a workaround)
-
-
-
- class SingletonExample
- {
-
-
-
- private volatile static SingletonExample obj = null;
-
-
-
-
- private static readonly object SyncLock = new object();
-
-
-
-
- public SingletonExample()
- {
-
- }
-
-
-
-
-
- public static SingletonExample Initialise()
- {
- if(obj == null)
- {
- lock (SyncLock)
- {
- if (obj == null)
- {
- obj = new SingletonExample();
- }
- }
- }
- return obj;
- }
- }
In Java we have synchronized keyword to take the pain away.
- class SingletonExample
- {
-
-
-
- private volatile static SingletonExample obj;
-
-
-
-
- public SingletonExample()
- {}
-
-
-
-
-
- public static SingletonExample Initialise()
- {
- if(obj == null)
- {
- synchronized(SingletonExample.class)
- {
- if (obj == null)
- obj = new SingletonExample();
- }
- }
- return obj;
- }
- }
Thank you so much for visiting this blog, I hope you were helped by this. If you have any queries, please connect with me.
Have a good day :)