一、定义
单例就是一个实例。从始至终我们只需要维护这么一个实例,来节约资源。
二、实例
我们用构造函数创建实例,现在我们要维护此类只维护一个实例,那么我们需要将生产实例的能力也就是构造函数加以限制。
并通过一个统一的函数对外公开我们维护的唯一的实例。
2.1 第一代单例模式:利用懒加载,在确实要使用实例的时候才会创建单例
public class Single_1 { private static Single_1 single = null; private Single_1() { } public static Single_1 GetInstance() { if (single == null) { single = new Single_1(); Console.WriteLine("创建实例"); } return single; } }
保证创建一个实例,但是只是在单线程的环境下,如果多线程会怎么样?试试!!
客户端并发100线程:
//------------------------单例模式----------------------- System.Threading.Tasks.Parallel.For(0, 100, t => { Singleton.Single_1.GetInstance(); }); Console.ReadKey();
运行结果:运行结果由系统随即切片,可能结果不同。但是确实存在创建了多个实例。
2.2 针对多线程之间的同步问题:加锁
public class Single_2 { private static Single_2 single = null; private static object lockkey = new object(); private Single_2() { } public static Single_2 GetInstance() { lock (lockkey) { if (single == null) { single = new Single_2(); Console.WriteLine("创建实例"); } return single; } } }
效率高点的双检锁:
public static Single_2 GetInstance() { if (single == null) { lock (lockkey) { if (single == null) { single = new Single_2(); Console.WriteLine("创建实例"); } } } return single; }
2.3 静态构造函数构造单例:我们知道静态构造函数是线程安全的
public class Single_3 { private static Single_3 single = null; private Single_3() { } static Single_3() { single = new Single_3(); Console.WriteLine("静态实例"); } public static Single_3 GetInstance() { return single; } }
三、总结
合理使用单例模式可以提高性能节约内存。当然,现实项目中有很多的例子,至少项目中可以很常见单例子模式。