设计模式 - 单例模式
含义: 保证一类仅有一个实例,并提供一个访问它的全局访问点
优缺点:
- 优点:
- 确保所有对象都访问一个实例
- 节省内存,避免频繁地创建、销毁对象
- 避免对共享资源的多重占用
- 缺点:
- 违背了"单一职责原则"
- 可扩展性差
实现过程:
- 保证单一实例:创建private static类型的对象instance,其为空时才new实例化创建
- 全局访问点:创建public类GetInstance()方法用于全局访问instance,并担当检测、new instance的责任
概念图:
代码实现:
//单例类: class Singleton { //私有化的构造函数 private Singleton() { Console.WriteLine("This is a SingleObject"); } //单一的实例 private static Singleton instance; //全局访问点 public static Singleton GetInstance() { //如果实例为空,则new一个新实例 if (instance == null) { instance = new Singleton(); Console.WriteLine("Create a new Instance"); } else { Console.WriteLine("Get a Instance"); } return instance; } } //测试类: class Program { static void Main(string[] args) { Singleton s1 = Singleton.GetInstance2(); Singleton s2 = Singleton.GetInstance2(); /* OUT: This is a SingleObject Create a new Instance Get a Instance */ } }
单例模式分类
根据new关键字实例化单例的先后顺序,可把单例模式分为饿汉式单例、懒汉式单例:
饿汉式:开始时就实例化instance
- 优点:线程安全(因为instance是static类型)
- 缺点:不管是否使用对象,开始时就实例化并占用了空间。即空间换时间
懒汉式:需要时才实例化instance
- 优点:资源利用率高。即时间换空间
- 缺点:多线程下存在隐患
//饿汉式:开始时就实例化instance public class Singleton { private Singleton (){} private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } //懒汉式:需要时才实例化instance //上一段代码同为懒汉式 public class Singleton { private Singleton (){} private static Singleton instance; public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
多线程中的单例
在上述懒汉式单例中,若多个线程同时进行到if (instance == null)
,会全部检测通过,最终造成多线程下创建了多个实例,即 多线程不安全。因此需要对多线程下的单例模式进行调整,使用 lock机制实现线程安全:
//饿汉式 + 线程安全 + 单锁 class Singleton { private Singleton() {} private static Singleton instance; //静态只读对象用于辅助实现lock