double check locking in singleton pattern

前端 未结 6 1185
死守一世寂寞
死守一世寂寞 2021-01-17 08:14

it may be basic question

to have a singleton in multi-threaded environment we can use a lock. Please refer the code snippet. But why do we need double-checked locki

相关标签:
6条回答
  • 2021-01-17 08:32

    If you create the object in the field initialiser, you don't need the lock:

    class singleton
    {
        private static singleton instance = new singleton();
        private static singleton() { }
    
        public static singleton Instance
        {
            get { return instance; }
        }
    }
    

    Also - bear in mind that the lock is only controlling the creation of the object, the object would still need to be thread-safe if you're using it in multiple threads.

    0 讨论(0)
  • 2021-01-17 08:33

    Multithreaded Singleton : The best approach to use double check locking

    public sealed class Singleton
    {
       private static volatile Singleton _instance;
       private static readonly object InstanceLoker= new Object();
    
       private Singleton() {}
    
       public static Singleton Instance
       {
          get 
          {
             if (_instance == null) 
             {
                lock (InstanceLoker) 
                {
                   if (_instance == null) 
                      _instance = new Singleton();
                }
             }
    
             return _instance;
          }
       }
    }
    
    0 讨论(0)
  • 2021-01-17 08:43

    And with .Net 4.x and newer you should defer to the Lazy class when possible as this pattern is used with the Initialization And Publication option. (note: the inverse is available as well where creation isn't thread safe but the publication of the instance is via the Publication option)

    0 讨论(0)
  • 2021-01-17 08:45

    Jon Skeet explains this in detail.

    Locks are expensive.
    If the object already exists, there's no point in taking out a lock.
    Thus, you have a first check outside the lock.

    However, even if the object didn't exist before you took the look, another thread may have created it between the if condition and the lock statement.
    Therefore, you need to check again inside the lock.

    However, the best way to write a singleton is to use a static constructor:

    public sealed class Singleton
    {
        private Singleton()
        {
        }
    
        public static Singleton Instance { get { return Nested.instance; } }
    
        private class Nested
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static Nested()
            {
            }
    
            internal static readonly Singleton instance = new Singleton();
        }
    } 
    
    0 讨论(0)
  • 2021-01-17 08:47

    When we try to execute the method of the singleton class using Parallel libraries. It doesn’t recognize the singleton behavior because of multi threading is executing in TPL which causes to failure of concept Singleton Pattern . To overcome this problem there is concept of the locking of the object so that at a time only one thread can access it. But this is not efficient approach because involvement of lock checking creates unnecessary watches to the object. To avoid it we make use “Double locking checking”

    0 讨论(0)
  • 2021-01-17 08:57

    The "best" way I know is this:

    public class MySingleton {
        // object for synchronization
        private static readonly object syncRoot = new object();
        // the singleton instance
        private static MySingleton @default;
    
        public static MySingleton Default {
            get {
                // geting singleton instance without locking
                var result = @default;
                // if result is NOT null, no additional action is required
                if ( object.ReferenceEquals(result, null) ){
                    // lock the synchronization object
                    lock(syncRoot) {
                        // geting singleton instanc in lock - because
                        // the value of @default field could be changed
                        result = @default;
    
                        // checking for NULL
                        if ( object.ReferenceEquals(result, null) ) {
                            // if result is NULL, create new singleton instance
                            result = new MySingleton();
                            // set the default instance
                            @default = result;
                        }
                    }
                }
    
                // return singleton instance
                return result;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题