• 设计模式之单例模式


    单例模式:

    核心思想:类只实例化一次,并且提供一个全局访问点。(只有那个全局访问点对外开放,其他内容封装起来)

    图片解析:

    优点:

    1由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能

     

    2直到对象要求产生一个实例才执行实例化;这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的 singleton

     

    代码:

    第一版本:(在单线程里面使用(不考虑线程内安全问题))

    主要分为三步:1、静态实例变量(用于接收实例成员)2、构造函数私有化(外部不能实例化,不能获得实例)3、全局访问点(任何用户都从这里访问)

     

     1     //sealed:私有类:太监类(不能被继承)
     2     public sealed class Singleton
     3     {
     4         //第一步:创建一个 静态 私有的变量(用于接收 对象的实例)
     5         private static Singleton instance;
     6 
     7         //第二步:构造函数私有化(不能实例化)
     8         private Singleton()
     9         {
    10         }
    11 13 
    14         //第三步:单例函数的“全局入口点” 静态
    15         public static Singleton Instance
    16         {
    17             get
    18             {
    19                 //(唯一实例):没有就进行创建,有的话就不创建
    20                 if (instance == null)
    21                 {
    22                     instance = new Singleton();
    23                 }
    24                 return instance;
    25             }
    26         }
    27     } 

     

     

    第二版本:(解决线程内安全问题)

    使用lock锁的机制,解决多线程问题。但是在性能上降低的

     

     1     //sealed:私有类:太监类(不能被继承)
     2     public sealed class Singleton
     3     {
     4         //第一步:创建一个 静态 私有的变量(用于接收 对象的实例)
     5         private static Singleton instance;
     6 
     7         //第二步:构造函数私有化(不能实例化)
     8         private Singleton()
     9         {
    10         }
    11 
    12         //第一版本的单例设计模式
    13 
    14         //第三步:单例函数的“全局入口点” 静态
    15         public static Singleton Instance
    16         {
    17             get
    18             {
    19                 //(唯一实例):没有就进行创建,有的话就不创建
    20                 if (instance == null)
    21                 {
    22                     instance = new Singleton();
    23                 }
    24                 return instance;
    25             }
    26         }
    27     } 

     

    3.第三版本:双重锁定机制

    优点:
    1》多线程安全

    2》(*重点*)线程不是每次都加锁(单线程不用加lock,性能提升了)

    3》允许实例化延迟到第一次访问对象时发生(只有第一次才创建)

     

     1     public sealed class singleton
     2     {
     3         private static singleton instance = null;
     4         private static readonly object padlock = new object();//用于锁的使用
     5         private singleton()
     6         {
     7         }
     8 
     9         public static singleton instance
    10         {
    11             get
    12             {
    13                 //双重锁定 (点线程里面 就不使用 lock,在性能上做了优化)
    14                 if (instance == null)
    15                 {
    16                     //将当前线程 锁住:造成 资源额外的开销,造成性能上的降低 (内部会进行 很多的处理)
    17                     lock (padlock)
    18                     {
    19                         if (instance == null)
    20                         {
    21                             instance = new singleton();
    22                         }
    23                     }
    24                 }
    25                 return instance;
    26             }
    27         }
    28     }

    4.第四版本:静态初始化(饿汉模式)这就和.Net的框架挂钩,这是在.Net里面推荐的使用方式:代码简便并效率高

    特点:

    1、(*)“依赖”.Net Framwork 内部进行处理 变量的初始化。
    2、对实例化的控制很少(大部分都是.Net内部实现的)

    3、饿汉模式是“首先方法”

     1     public sealed class Singleton
     2     {
     3         //静态只读的属性
     4         private static readonly Singleton instance = null;
     5 
     6         //静态构造函数:只要是在内存里面加载这个类(不管是实例化,还是调用这个类的静态成员)都会执行这个静态构造函数,并且不会消失
     7         //保证了线程内唯一:因为只实例化一次
     8         static Singleton()
     9         {
    10             instance = new Singleton();
    11         }
    12 
    13         //私有构造函数:保证类不能被实例化
    14         private Singleton()
    15         {
    16         }
    17 
    18         //全局入口点
    19         public static Singleton Instance
    20         {
    21             get
    22             {
    23                 return instance;
    24             }
    25         }
    26 
    27     }

    上面的有一种问题,就是如果我的类里面如果有一个 静态方法SayHi(),在调用这个方法的时候,我不想将这个对象进行实例化,但是因为是静态构造函数,所以只要调用和这个类有关的对象都会调用静态构造函数,就会初始化实例化。解决方法:将静态初始化放到嵌套类里面。这样就不存在静态构造函数了,因为已经将他的静态初始化作用转移到了嵌套类里了。

    5、最终版本:单例模式之饿汉模式 最终版(延迟初始化)

     将初始化 的工作 交给了 嵌套类 Nested 的静态构造函数,所以  调用不想 初始化  对象 的 代码时 就不会执行

     1     public sealed class Singleton
     2     {
     3 
     4         //不再使用静态构造函数 (但是他的  线程内唯一的  功能必须要实现)
     5         //static Singleton()
     6         //{
     7 
     8         //}
     9 
    10         private Singleton()
    11         {
    12 
    13         }
    14 
    15         public static Singleton Instance
    16         {
    17             get
    18             {
    19                 return Nested.instance;
    20             }
    21         }
    22 
    23         //调用这个方法的时候我并不想 调用 那个静态构造函数,对 其对象进行实例化
    24         public static void SayHi()
    25         {
    26             Console.WriteLine("Hello");
    27         }
    28 
    29 
    30         //解决上面的问题 使用静态类,通过这个静态 进行对 上面的那个类 进行 实例化
    31 
    32         private class Nested
    33         {
    34             //注意这里不能是  private;因为那样的话 在外层类 里面就不能访问到了
    35             internal static readonly Singleton instance = null;
    36 
    37             //将 外层类的  静态构造函数的功能在 下面这个 静态构造函数实现了(线程内唯一)
    38             static Nested()
    39             {
    40                 instance = new Singleton();
    41             }
    42         }
    43     }
  • 相关阅读:
    微服务-SpringCloud学习系列(二):注册中心Eureka
    Spring Security系列(一)简介
    程序人生(一)--习惯与性格
    JavaEE系列(一)--Filter技术
    JavaEE系列(一)--Servlet技术
    微服务-SpringCloud学习系列(一):认识微服务
    mongoDB安装
    php遍历目录下的文件
    mysql创建视图
    ssh 安全策略
  • 原文地址:https://www.cnblogs.com/xiaoxiaogogo/p/3451207.html
Copyright © 2020-2023  润新知