含义: 保证一类仅有一个实例,并提供一个访问它的全局访问点

优缺点:

  • 优点:
    • 确保所有对象都访问一个实例
    • 节省内存,避免频繁地创建、销毁对象
    • 避免对共享资源的多重占用
  • 缺点:
    • 违背了"单一职责原则"
    • 可扩展性差

实现过程:

  1. 保证单一实例:创建private static类型的对象instance,其为空时才new实例化创建
  2. 全局访问点:创建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