Click here to Skip to main content
15,888,454 members
Please Sign up or sign in to vote.
1.80/5 (2 votes)
See more:
Hello guys,

I just started learning this Design Pattern I am little bit confused about Singleton pattern because when search same question on google I found different way to implement it. But I want to know which is best method what is difference in these ways of implementing.

1- No Thread Safe Singleton.
2- Thread-Safety Singleton.
3- Thread-Safety Singleton using Double-Check Locking.
4- Thread-Safe Singleton without using locks and no lazy instantiation.
5- Fully lazy instantiation.
6- Using .NET 4's Lazy<t> type.


Thanks in advance for prompt reply!!
Posted
Updated 30-Dec-16 6:56am
v3
Comments
Andy Lanng 22-Sep-15 8:19am    
Personally: 6- Using .NET 4's Lazy type.
_AQ 22-Sep-15 8:21am    
thanks..
Richard Deeming 22-Sep-15 9:06am    
I assume you read the article[^] which explains these options in depth?

Did you not read the conclusion at the bottom?
Philippe Mori 31-Dec-16 13:11pm    
Singleton is a anti pattern. Best way to use it is to not use it.

Bing: singleton anti pattern

Unsafe Way with Lazy Loading :-
public class Program
    {
        public static void Main(string[] args)
        {
            //Once you call this it will check if _instance is not null and call the constructor if null else return the existing one.
            var singletonInstance1 = Task.Run<Singleton>(() => Singleton.Intance());

            //If we try to execute two lines one by one of different thread, which causes to a unsafe call to _instance. Because two different task can go inside the Intance() function and call the constructor twice. Although _instance is static and initialize only once but can raise two calls.
            var singletonInstance2 = Task.Run<Singleton>(() => Singleton.Intance());
        }
    }

    public class Singleton
    {
        //It should has Private / Protected constructor, so can not be called from outside of class.
        private Singleton()
        { }

        //Static field to hold instance of singleton class. This will be initialized on demand.
        private static Singleton _instance;
        public static Singleton Intance()
        {
            if (_instance == null)
                return new Singleton();
            else
                return _instance;
        }
    }



Thread Safe ways with Eager Loading :-

public class Singleton
   {
       //It should has Private / Protected constructor, so can not be called from outside of class.
       private Singleton()
       { }

       //Now we called the constructor before executing the Instance() method. So _instance can not be null in this case.
       private static Singleton _instance = new Singleton();
       public static Singleton Intance()
       {
           //No Need to check _instance is null or not, because it will always available.
           return _instance;
       }
   }



Thread safe with Lazy loading :-

public class Singleton
    {
        //It should has Private / Protected constructor, so can not be called from outside of class.
        private Singleton()
        { }

        //Static field to hold instance of singleton class. This will be initialized on demand.
        private static Singleton _instance;
        public static Singleton Intance()
        {
            //use lock to create a thread safe call to _instance variable. Here before checking _instance variable we locked that object so no other thread can use it until free.
            lock (_instance) ;
            if (_instance == null)
                return new Singleton();
            else
                return _instance;
            
        }
    }
 
Share this answer
 
v2
Comments
Jon McKee 30-Dec-16 20:29pm    
Not sure who gave you the one star, I think your first two examples are fine at a glance, but your 3rd example has a major flaw.
  lock (_instance) ; //You're releasing the lock before checking the unsafe code
  if (_instance == null)

Now in practice this might help as the delay between one thread releasing the lock and the next thread picking it up might allow the first thread to fully execute the singleton creation, but this is not a guarantee. You should be using double-check locking instead.
  if (_instance == null)
    lock (_instance)
      if (_instance == null)
        return new Singleton();
      else
        return _instance;
  else
    return _instance;

In addition, you should also not be locking on the _instance. You never want to lock on something that is shared because you could run into deadlock scenarios. Create an object like private static readonly object _instanceLock = new object(); and lock on that.

I'd also like to point out you never assign the new singleton creation in examples 1 and 3. You simply return it ^^
As you ask - I am implementing a new SignalR Hub and Ticker. Here is my Ticker singleton (6- Using .NET 4's Lazy type.)

C#
public class ServicesTicker
{
    // Singleton instance
    private readonly static Lazy<ServicesTicker> _instance = new Lazy<ServicesTicker>(
        () => new ServicesTicker(GlobalHost.ConnectionManager.GetHubContext<ServicesHub>().Clients));

    public static ServicesTicker Instance { get { return _instance.Value; } }

    private IHubConnectionContext<dynamic> Clients { get; set; }

    private ServicesTicker(IHubConnectionContext<dynamic> clients)
    {
        Clients = clients;
    }
}


I would have included this in the comment but the code section would look bad
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900