Singleton Design Pattern

Singleton design pattern can be implemented in the following ways.

1. Lazy Instantiation

Advantage: Lazy instantiation avoids instantiating unnecessary singletons when the application starts.

Disadvantage: The main disadvantage of this implementation, however, is that it is not safe for multi-threaded environments. If separate threads of execution enter the Instance property method at the same time, more than one instance of the Singleton object may be created

1:    public class Singleton  
2:    {  
3:      private static Singleton instance;  
4:      private Singleton() { }  
5:      public static Singleton Instance  
6:      {  
7:        get  
8:        {  
9:          if (instance == null)  
10:          {  
11:            instance = new Singleton();  
12:          }  
13:          return instance;  
14:        }  
15:      }  
16:    }  

2. Static Initialization

Advantage: In this strategy, the instance is created the first time any member of the class is referenced. The common language run-time takes care of the variable initialization. The class is marked sealed to prevent derivation, which could add instances In addition, the variable is marked read-only, which means that it can be assigned only during static initialization (which is shown here) or in a class constructor.

Disadvantage: The only potential downside of this approach is that you have less control over the mechanics of the instantiation.

1:    public sealed class Singleton  
2:    {  
3:      private static readonly Singleton instance = new Singleton();  
4:      private Singleton() { }  
5:      public static Singleton Instance  
6:      {  
7:        get  
8:        {  
9:          return instance;  
10:        }  
11:      }  
12:    }  

3. Multithreaded Singleton (Double-Check Locking)

Advantage: Double-Check locking to keep separate threads from creating new instances of the singleton at the same time. This approach ensures that only one instance is created and only when the instance is needed. The variable is declared to be volatile to ensure that assignment to the instance variable completes before the instance variable can be accessed.

This approach uses a syncRoot instance to lock on, rather than locking on the type itself, to avoid deadlocks.

This double-check locking approach solves the thread concurrency problems while avoiding an exclusive lock in every call to the Instance property method. It also allows you to delay instantiation until the object is first accessed.

Disadvantage: In practice, an application rarely requires this type of implementation. In most cases, the static initialization approach is sufficient.

1:    public sealed class Singleton  
2:    {  
3:      private static volatile Singleton instance;  
4:      private static object syncRoot = new Object();  
5:      private Singleton() { }  
6:      public static Singleton Instance  
7:      {  
8:        get  
9:        {  
10:          if (instance == null)  
11:          {  
12:            lock (syncRoot)  
13:            {  
14:              if (instance == null)  
15:                instance = new Singleton();  
16:            }  
17:          }  
18:          return instance;  
19:        }  
20:      }  
21:    }  

Where to use Singletons?

thread pools, connections, caches, dialog boxes, objects that handle preferences and registry settings, objects used for logging etc.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s