Singleton模式与多线程

Singleton模式在多线程环境下是否线程安全?本文实现了线程安全的单件模式。

//Singleton pattern implemented
public sealed class CachingService
{
   //syncIndicator. -- thread synchonization
   private static readonly object syncObject = new object(); 
 
   //The unique instance. -- volatile to allow multi-threading
   private static volatile CachingService serviceInstance; 
   
   //Blank default constructor
   private CachingService(){}
   
   public static CachingService Value    
   {
     get
     {
       //in multi-threads, the next statement result will be different, 
       //because of the execution sequence
 
       if(serviceInstance == null) 
       {
         lock(syncObject)
         {
            if(serviceInstance == null)
               serviceInstance = new CachingService();
         }
       }
       return serviceInstance;
 
     }//end of get
   }//end of Value property
}

也有一种巧妙的写法可以避免使用double-checked locking:

public class Singleton
{
       private static class LazyHolder
       {
           public static readonly Singleton Instance = new Singleton();
       }
 
       private Singleton(){}
 
       public static Singleton GetInstance()
       {
           return LazyHolder.Instance;
       }
}

原因:

当CLR加载class Singleton的时候,因为Singleton没有static variables需要被初始化,所以Singleton的初始化其实什么也没做。而对static class LazyHolder来说,直到它被执行的时候才会被初始化。而static class LazyHolder只有载Singleton.GetInstance()被执行的时候才会执行到。当第一次调用GetInstance()的时候 CLR才会加载和初始化LazyHolder这个class。

对于LazyHolder class的初始化就是对其静态变量static variable Instance的初始化。而Instance的初始化就是执行Singleton的private constructor。因为.NET保证class的initialization是serial的,就是说在加载和初始化的过程中我们不需要自己做同步。因为初始化过程是一个serial的操作,所以对于后面的GetInstance,我们不需要做任何同步,它也会返回一个正确初始化的 Singleton对象。

原文地址:https://www.cnblogs.com/Mainz/p/1255801.html