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对象。