Lazy Loading and Eager loading in Singleton Design Pattern

Lazy Loading and Eager Loading in Singleton Design Pattern

In this article, I am going to discuss the Lazy Loading and Eager Loading in Singleton Design Pattern to achieve thread-safety with an example. Please read our previous article before proceeding to this article where we discussed the Thread-safe Singleton Design Pattern in C# with examples. As part of this article, we are going to discuss the following pointers.

  1. What is Non-Lazy or Eager Loading?
  2. What is Lazy or Deferred Loading?
  3. Understanding The Lazy Keyword in C#.
  4. How to make the singleton instance thread-safe using both Eager loading and Lazy loading?
What is Non-Lazy or Eager Loading in C#?

The Eager loading in singleton design pattern is nothing a process in which we need to initialize the singleton object at the time of application start-up rather than on-demand and keep it ready in memory to be used in the future. The advantage of using Eager Loading in the Singleton design pattern is that the CLR (Common Language Runtime) will take care of object initialization and thread-safety. That means we will not require to write any code explicitly for handling the thread-safety for a multithreaded environment.

Let’s understand the Eager Loading using the Singleton design pattern with one example. Add a class with the name Singleton.cs and then copy and paste the following code.

Singleton.cs
namespace SingletonDemo
{
    public sealed class Singleton
    {
        private static int counter = 0;

        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }

        private static readonly Singleton singleInstance = new Singleton(); 
        
        public static Singleton GetInstance
        {
            get
            {
                return singleInstance;
            }
        }

        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}

In the above example, the following line of code creates the Singleton instance at the time of application startup.

private static readonly Singleton singleInstance = new Singleton();

Modify the Main method of the Program class as shown below to use the singleton instance.

Program.cs
namespace SingletonDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Parallel.Invoke(
                () => PrintTeacherDetails(),
                () => PrintStudentdetails()
                );
            Console.ReadLine();
        }

        private static void PrintTeacherDetails()
        {
            Singleton fromTeacher = Singleton.GetInstance;
            fromTeacher.PrintDetails("From Teacher");
        }

        private static void PrintStudentdetails()
        {
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");
        }
    }
}

Now run the application and you will see the following output:

Lazy Loading and Eager loading in Singleton Design Pattern

 

 

You can see that only one instance got created as the Counter value is 1. The above Singleton class is thread-safe after removing the lock variables. This is because the now the CLR (Common Language Runtime) will internally take care of the variable initialization as well as thread safety in eager loading.

What is Lazy or Deferred Loading in C#?

The Lazy or Deferred Loading is a design pattern or you can say its a concept which is commonly used to delay the initialization of an object until the point at which it is needed. So the main objective of Lazy loading is to load the object on-demand or you can say object when needed. The most important point that you need to keep in mind is that, you need to use the Lazy loading when the cost of the object creation is very high as well as the use of that object is very rare. The lazy loading improves the performance of an application if it is used properly. We can use the Lazy keyword to make the singleton instance as lazy loading. 

Understanding The Lazy Keyword in C#:

The lazy keyword which was introduced as part of .NET Framework 4.0 provides the built-in support for lazy initialization i.e. on-demand object initialization. If you want to make an object (such as Singleton) as lazily initialized then you just need to pass the type (Singleton) ) of the object to the lazy keyword as shown below.

private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton());

The most important point that you need to remember is the Lazy<T> objects are by default thread-safe. In a multi-threaded environment, when multiple threads are trying to access the same Get Instance property at the same time, then the lazy object will take care of thread safety.

Lazy Loading in Singleton Design Pattern with an example.

We need to pass a delegate to the constructor which calls the Singleton constructor, which is done most easily with a lambda expression. Modify the singleton class as shown below.

namespace SingletonDemo
{
    public sealed class Singleton
    {
        private static int counter = 0;

        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }

        private static readonly Lazy<Singleton> Instancelock =
                    new Lazy<Singleton>(() => new Singleton());

        public static Singleton GetInstance
        {
            get
            {
                return Instancelock.Value;
            }
        }

        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}

Modify the main method of the Program class as shown below.

namespace SingletonDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Parallel.Invoke(
                () => PrintTeacherDetails(),
                () => PrintStudentdetails()
                );
            Console.ReadLine();
        }

        private static void PrintTeacherDetails()
        {
            Singleton fromTeacher = Singleton.GetInstance;
            fromTeacher.PrintDetails("From Teacher");
        }

        private static void PrintStudentdetails()
        {
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");
        }
    }
}

Now run the application and see the output.

Lazy Loading and Eager loading in Singleton Design pattern

 

 

We got the same output as Eager Loading. This is because of the lazy keyword which creates only one singleton instance and also they are by default thread-safe that’s why we do not get any error while invoking the methods parallelly.

In the next article, I am going to discuss the difference between static class vs Singleton class with some examples. Here, in this article, I try to explain Lazy Loading and Eager Loading in Singleton Design pattern step by step with a simple example. I hope this article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.

2 thoughts on “Lazy Loading and Eager loading in Singleton Design Pattern”

Leave a Reply

Your email address will not be published. Required fields are marked *