Singleton Pattern belongs to Creational type pattern. As the name implies, creational design type deals with object creation mechanisms. Basically, to simplify this, creational pattern explains us the creation of objects in a manner suitable to a given situation.
Singleton design pattern is used when we need to ensure that only one object of a particular class is Instantiated. That single instance created is responsible to coordinate actions across the application.
Singleton design pattern is used when we need to ensure that only one object of a particular class is Instantiated. That single instance created is responsible to coordinate actions across the application.
If you look at the illustrated diagram above, you will see different objects trying to invoke an object instantiated as singleton. This single instance of the object is responsible to invoke underneath methods or events.
Advantages and Guidelines for Singleton implementation.
Concurrent access to the resource is well managed by singleton design pattern.
As part of the Implementation guidelines we need to ensure that only one instance of the class exists by declaring all constructors of the class to be private. Also, to control the singleton access we need to provide a static property that returns a single instance of the object.
Singleton Class Implementation Example
Concurrent access to the resource is well managed by singleton design pattern.
As part of the Implementation guidelines we need to ensure that only one instance of the class exists by declaring all constructors of the class to be private. Also, to control the singleton access we need to provide a static property that returns a single instance of the object.
Singleton Class Implementation Example
Program.cs
namespace SingletonDemo
{
class Program
{
static void Main(string[] args)
{
/*
* Assuming Singleton is created from employee class
* we refer to the GetInstance property from the Singleton class
*/
Singleton fromEmployee = Singleton.GetInstance;
fromEmployee.PrintDetails("From Employee");
/*
* Assuming Singleton is created from student class
* we refer to the GetInstance property from the Singleton class
*/
Singleton fromStudent = Singleton.GetInstance;
fromStudent.PrintDetails("From Student");
Console.ReadLine();
}
}
}
Singleton.cs
namespace SingletonDemo
{
/*
* Sealed ensures the class being inherited and
* object instantiation is restricted in the derived class
*/
public sealed class Singleton
{
private static int counter = 0;
/*
* Private property initilized with null
* ensures that only one instance of the object is created
* based on the null condition
*/
private static Singleton instance = null;
/*
* public property is used to return only one instance of the class
* leveraging on the private property
*/
public static Singleton GetInstance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
/*
* Private constructor ensures that object is not
* instantiated other than with in the class itself
*/
private Singleton()
{
counter++;
Console.WriteLine("Counter Value " + counter.ToString());
}
/*
* Public method which can be invoked through the singleton instance
*/
public void PrintDetails(string message)
{
Console.WriteLine(message);
}
}
}
Lazy Initialization in Singleton : GetInstance Property is responsible for the Singleton Instance creation. Singleton object is not instantiated until and unless GetInstance is invoked. Hence, there is a delay in instance creation till the GetInstance is accessed. This Delay in Instance creation is called Lazy Initialization.
How to use Multithreads in Singleton : The lazy initialization works perfectly well when we invoke the GetInstance in a Single threaded approach. However, there is a chance that we may end up creating multiple instances when multiple threads invoke the GetInstance at the same time.
This Thread racing situation causes thread safety issues in Singleton Initialization and further the current code ends up in creating multiple instances of Singleton objects in memory.
To achieve and replicate multiple threads accessing GetInstance, We have modified the main program by using Parallel.Invoke method of .NET Framework 4.0. Please refer to Main program code below for more details.
How to implement a Thread Safe singleton class : Locks are the best way to control thread race condition and they help us to overcome the present situation. Please refer to the Singleton.cs code for lock checks and double check locking.
How to use Multithreads in Singleton : The lazy initialization works perfectly well when we invoke the GetInstance in a Single threaded approach. However, there is a chance that we may end up creating multiple instances when multiple threads invoke the GetInstance at the same time.
This Thread racing situation causes thread safety issues in Singleton Initialization and further the current code ends up in creating multiple instances of Singleton objects in memory.
To achieve and replicate multiple threads accessing GetInstance, We have modified the main program by using Parallel.Invoke method of .NET Framework 4.0. Please refer to Main program code below for more details.
How to implement a Thread Safe singleton class : Locks are the best way to control thread race condition and they help us to overcome the present situation. Please refer to the Singleton.cs code for lock checks and double check locking.
static void Main(string[] args)
{
Parallel.Invoke(
() => PrintStudentdetails(),
() => PrintEmployeeDetails()
);
Console.ReadLine();
}
private static readonly object obj = new object();
public static Singleton GetInstance
{
get
{
if (instance == null)
{
lock (obj)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
Difference between Lazy Initialization and Eager Initialization
Lazy Initialization:
The lazy initialization of an object improves the performance and avoids unnecessary computation till the point the object is accessed. Further, it reduces the memory footprint during the start-up of the program. Reducing the memory print will help faster loading of the application.
Non-Lazy or Eager Loading:
Eager loading is nothing but to initialize the required object before it’s being accessed. Which means, we instantiate the object and keep it ready and use it when we need it. This type of initialization is used in lower memory footprints. Also, in eager loading, the common language runtime takes care of the variable initialization and its thread safety. Hence, we don’t need to write any explicit coding for thread safety.
Singleton with Lazy keyword (.NET 4.0):
Lazy keyword provides support for lazy initialization. In order to make a property as lazy, we need to pass the type of object to the lazy keyword which is being lazily initialized.
By default, Lazy<T> objects are thread-safe. In multi-threaded scenarios, the first thread which tries to access the Value property of the lazy object will take care of thread safety when multiple threads are trying to access the Get Instance at the same time.
Therefore, it does not matter which thread initializes the object or if there are any thread race conditions that are trying to access this property.
The lazy initialization of an object improves the performance and avoids unnecessary computation till the point the object is accessed. Further, it reduces the memory footprint during the start-up of the program. Reducing the memory print will help faster loading of the application.
Non-Lazy or Eager Loading:
Eager loading is nothing but to initialize the required object before it’s being accessed. Which means, we instantiate the object and keep it ready and use it when we need it. This type of initialization is used in lower memory footprints. Also, in eager loading, the common language runtime takes care of the variable initialization and its thread safety. Hence, we don’t need to write any explicit coding for thread safety.
Singleton with Lazy keyword (.NET 4.0):
Lazy keyword provides support for lazy initialization. In order to make a property as lazy, we need to pass the type of object to the lazy keyword which is being lazily initialized.
By default, Lazy<T> objects are thread-safe. In multi-threaded scenarios, the first thread which tries to access the Value property of the lazy object will take care of thread safety when multiple threads are trying to access the Get Instance at the same time.
Therefore, it does not matter which thread initializes the object or if there are any thread race conditions that are trying to access this property.
private static readonly Lazy<Singleton> instance =
new Lazy<Singleton>(()=>new Singleton());
Differences between Singleton and static classes
1. Static is a keyword and Singleton is a design pattern
2. Static classes can contain only static members
3. Singleton is an object creational pattern with one instance of the class
4. Singleton can implement interfaces, inherit from other classes and it aligns with the OOPS concepts
5. Singleton object can be passed as a reference
6. Singleton supports object disposal
7. Singleton object is stored on heap
8. Singleton objects can be cloned
Real world usage of Singleton:
Listed are few real world scenarios for singleton usage
Listed are few real world scenarios for singleton usage
1. Exception/Information logging
2. Connection pool management
3. File management
4. Device management such as printer spooling
5. Application Configuration management
6. Cache management
7. And Session based shopping cart are some of the real world usage of singleton design pattern
Real World Example
No comments:
Post a Comment
This is a User Friendly Blog.
Simple Interface and Simple Controls are used.
Post your comments so i can modify blog regarding your wish.