Introduction
The Singleton Design Pattern is one of the most commonly used design patterns in C#. It ensures that a class has only one instance and provides a global access point to that instance.
However, in multi-threaded applications, creating a thread-safe Singleton becomes very important. If not handled correctly, multiple threads can create multiple instances, which breaks the purpose of Singleton.
In this article, we will learn how to implement a thread-safe Singleton using Lazy in simple words.
What is Singleton Design Pattern?
Singleton means:
Only one instance of a class should exist
That instance should be globally accessible
Example use cases:
Logging service
Configuration manager
Database connection manager
Basic idea:
You don’t allow users to create objects directly. Instead, you control the instance creation inside the class.
Problem with Traditional Singleton (Not Thread-Safe)
Let’s see a simple Singleton example:
public class Singleton
{
private static Singleton _instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
Problem:
If two threads access Instance at the same time
Both may create a new object
Result:
❌ Multiple instances created
This breaks thread safety.
What is Thread Safety?
Thread safety means that your code works correctly even when multiple threads run at the same time.
In Singleton:
Only one instance should be created
No matter how many threads access it
Traditional Fix: Locking (But Not Efficient)
private static readonly object _lock = new object();
public static Singleton Instance
{
get
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
Problem:
Locking is slow
Performance overhead
This is where Lazy helps.
What is Lazy in C#?
Lazy is a built-in class in .NET that ensures:
Object is created only when needed (lazy initialization)
Thread-safe by default
Simple meaning:
"Create the object only when someone asks for it, and do it safely."
How Lazy Solves Thread Safety
Lazy handles:
Thread synchronization internally
Ensures only one instance is created
Avoids unnecessary locking
Join the conversation! Your thoughts help the community grow.