-
Thread Safe Singleton using Lazy Loading
-
Creating a thread-safe singleton in C# using lazy loading is a common design pattern that ensures that a class has only one instance while providing a global point of access to it.
We have discussed lazy loading concept with the help of single lock and double lock in previous lessons, and in previous lesson, we have discussed about Eager Loading, where the instance creation is done at the starting of the applications, making the instance available at the initial stage.
With C# 4.0 onwards, we can use the Lazy
Generic class to make the Singleton Instance Lazy Loading. Here the instance is only created when it is first accessed which further helps in improving the performance of application. Let us proceed and see how we can implement Lazy Loading in the Singleton Design Pattern using the Lazy Generic Class in C#
Example of Lazy loading with Lazy keyword
public class Singleton { // The private constructor ensures that the class cannot be instantiated from outside. private Singleton() { // Initialization code } // The Lazy
instance will create the Singleton instance on first access. private static readonly Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton()); // Public property to provide access to the instance. public static Singleton Instance { return _instance.Value; } // Example method public void DoSomething() { // Method implementation } } class Program { static void Main(string[] args) { // Access the Singleton instance Singleton singleton = Singleton.Instance; singleton.DoSomething(); } }keyword
- Thread Safety: The Lazy
ensures that the singleton instance is created in a thread-safe manner without requiring explicit locking. - Lazy Initialization: The instance is only created when it is first accessed.
- Simplicity: The implementation is straightforward and easy to understand.
The Lazy
Generic Class, introduced as part of .NET Framework 4.0, provides built-in support for lazy initialization, i.e., on-demand object initialization. If you want to make an object (such as Singleton) lazily initialized, i.e., on-demand object initialization. You need to pass the type (Singleton) of the object to the Lazy generic class. Within the Lazy constructor, using the lambda expression, we need to create the instance, which is shown below. Lazy<Singleton> _instance = new Lazy<Singleton>(() => new Singleton());
ConclusionThe best practice for implementing a thread-safe singleton in C# is to use the Lazy
approach, which provides both lazy initialization and thread safety with minimal overhead. Avoid basic checks for null and inefficient locking mechanisms, as these can lead to errors or performance issues in multi-threaded environments. - Thread Safety: The Lazy