深入浅出设计模式-005:单例模式(Singleton Pattern)
一:单例模式,确保一个类只有一个实例,并提供一个全局访问点 单例模式确保程序中只有一个实例 单例模式也提供访问这个实例的全局点 确定在性能和资源上的限制,然后小心地选择适当的方案实现单例,以解决多线程的问题。
public sealed class Singleton1 { //缺点:如果同时有两个线程去判断(instance == null),并且得到的结果为真, // 这时两个线程都会创建类Singleton的实例,这样就违背了Singleton模式的原则。 //优点:由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能,即使它可能引入不想要的依赖性。 // 直到对象要求产生一个实例才执行实例化; // 这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的 singleton。 private static Singleton1 uniqueInstance = null; private Singleton1() { }
public static Singleton1 getInstance() { if (uniqueInstance == null) uniqueInstance = new Singleton1(); return uniqueInstance; } } public sealed class Singleton2 { //优点:线程安全 //缺点:每次执行操作时,都需要同步,而事实上只需要第一次构建时同步即可 private static Singleton2 uniqueInstance = null; private static Object syncRoot = new Object(); private Singleton2() { }
public static Singleton2 getInstance() { lock (syncRoot) ; if (uniqueInstance == null) { uniqueInstance = new Singleton2(); } return uniqueInstance; } } public sealed class Singleton3 { //优点:线程安全,采用双重加锁减少每次都同步的确定 //缺点:无法实现延迟初始化。 private volatile static Singleton3 uniqueInstance = null; private static Object syncRoot = new Object(); private Singleton3() { }
public static Singleton3 getInstance() { if (uniqueInstance == null) { lock (syncRoot) ; if (uniqueInstance == null) uniqueInstance = new Singleton3(); } return uniqueInstance; } } public sealed class Singleton4 { //优点:延迟加载,线程安全 //缺点:对实例化机制的控制权较少。 private static readonly Singleton4 uniqueInstance = new Singleton4(); static Singleton4() { } private Singleton4() { }
public static Singleton4 getInstance() { return uniqueInstance; } }
public sealed class Singleton5 { //静态构造函数,在调用时,和静态函数成员类似,都会被优先调用 //缺点:线程不安全 private static Singleton5 uniqueInstance = null; static Singleton5() { uniqueInstance = new Singleton5(); }
private Singleton5() { } public static Singleton5 getInstance() { return uniqueInstance; } } public sealed class Singleton6 { //静态构造函数,在调用时,和静态函数成员类似,都会被优先调用 //线程安全 private static Singleton6 uniqueInstance = null; private static System.Threading.Mutex mutex; static Singleton6() { uniqueInstance = new Singleton6(); mutex = new System.Threading.Mutex(); }
private Singleton6() { }
public static Singleton6 getInstance() { mutex.WaitOne(); return uniqueInstance; } public static void Release() { mutex.ReleaseMutex(); } } class Program { static void Main(string[] args) { Singleton1.getInstance(); Singleton2.getInstance(); Singleton3.getInstance(); Singleton4.getInstance(); Singleton5.getInstance(); Singleton6.getInstance(); } }