单例模式一般为共享数据使用,例如对象池、查看文件。为了防止创建多个对象,一般在单例模式中使用Private修饰符修饰,这样能确保在内部构建。如果包括类都是静态的一般用于没有变量的工具方法中。
一般防止在多线程中创建多个单例模式,有如下三种方法应对:
1)、在类的内部New好对象,这一般是能保证单例模式对象肯定用到才选择这个方法。
2)、使用双重加锁检查,使用Lock关键字,在内部外加一个if判断对象是否创建,再来创建。
3)、使用同步单线程,这个一般是在量不大的情况下使用。
常见的单例写法有:
(一):适用于单线程环境
public sealed class Singleton1 { private Singleton1() { } private static Singleton1 _instance = null; public static Singleton1 Instance { get { if (_instance == null) _instance = new Singleton1(); return _instance; } } }
(二):多线程适用,但效率不高
public sealed class Singleton2 { private Singleton2() { } private static Object o = new Object(); private static Singleton2 _instance = null; public static Singleton2 Instance { get { lock (o) { if (_instance == null) _instance = new Singleton2(); } return _instance; } } }
(三):加锁前二次判断,提高效率
public sealed class Singleton3 { private Singleton3() { } private static Object o = new Object(); private static Singleton3 _instance = null; public static Singleton3 Instance { get { if (_instance == null) { lock (o) { if (_instance == null) _instance = new Singleton3(); } } return _instance; } } }
(四):推荐方法①:静态构造函数(C#中静态构造函数实现的时机由CLR控制)
public sealed class Singleton4 { private Singleton4() { } private static Object o = new Object(); private static Singleton4 _instance = new Singleton4(); public static Singleton4 Instance { get { return _instance; } } }
(五):推荐方法②:使用内部类 (可控制构造函数的时机)
public sealed class Singleton5 { private Singleton5() { } private static Object o = new Object(); private static Singleton5 _instance = new Singleton5(); public static Singleton5 Instance { get { return Nested.instance; } } class Nested { static Nested() { } internal static readonly Singleton5 instance = new Singleton5(); } }
PS:C#有个Lazy对象,可以实现延迟加载的单例,推荐使用。