c# 单例模式的实现

作者:JN-SHao 时间:2023-06-12 01:16:44 

记一下学习单例模式的笔记:

单例就是要保证该类仅有一个实例。实现完全封闭的单例(外部不能new)其实就要两点要求:

  • 全局访问:需要一个该类型的全局静态变量,每次获取实例时都要判断它是否null,不存在new,存在通过一个方法直接返回该值获取实例来保证对象唯一;

  • 实例化控制:new实例不能外部new、造成实例不唯一,需要一个私有构造器禁用共有构造器。

根据new实例的时机,分为饿汉式和懒汉式:

一、 饿汉式单例:静态变量初始化时new

特点:加载时new,一开始全局就存在该唯一实例,每次用到只要获取就行,提前占用系统资源但不存在线程安全问题。代码如下:


public sealed class Singleton
 {
   private static readonly Singleton instance = new Singleton();
   private Singleton() { }

public static Singleton GetInstance()
   {
     return instance;
   }
 }

二、 懒汉式单例:需要该实例的时候再new

特点:真正需要用到的时候才实例化,不提前占用资源但多个线程同时用到该实例时,会存在判断静态变量都为null都去new而产生多个实例的情况。有线程安全问题,但可以用双重锁定解决。

单线程懒汉单例代码如下:


public class Singleton
 {
   private static Singleton instance = null;
   private Singleton() { }

public static Singleton GetInstance()
   {
     if (instance == null)
       instance = new Singleton();
     return instance;
   }
 }

多线程懒汉单例代码如下:


public class Singleton
 {
   private static Singleton instance = null;
   private static readonly object obj = new object();
   private Singleton() { }

public static Singleton GetInstance()
   {
     //双重锁定
     if (instance == null)//只有为null需要实例化处理时才进行加锁,提高性能避免不必要的等待
     {
       lock (obj)
       {
         if (instance == null)//避免其他线程等待锁释放期间有线程已经实例化,从而造成多个实例
           instance = new Singleton();
       }
     }
     return instance;
   }
 }

三、 注册式单例

介绍一个有意思的单例-泛型注册式,是对单例的扩展,主要了解它的设计思想。

其实每个类单例模式实现代码都是差不多的:

  1. 相同结构和成员(字段、属性、行为等):是否可以考虑进行抽象提取一个公共的调用接口?

  2. 成员类型或输入输出具体类型不是固定的:是否可以考虑设计一个适用于不同类型的通用处理方式而不都是Object?这个适用不同类型通用解决就要用到泛型。

实现代码如下(例子使用饿汉式,当然也可以用懒汉式):


public abstract class Singleton<T> where T:class,new()
 {
   private static readonly T instance = new T();
   protected Singleton() { }

public static T GetSingleton()//获取单例
   {
     return instance;
   }
 }
 public class Person : Singleton<Person> { }

可以看到这种单例通过继承的方式,既可以new实例也可以获取单例实例。如果要实现上面的完全封闭(禁用外部new),也可以完全在Person类中写个私有构造器在Singleton<T>类中实例的获取new T()改为反射调用私有构造器的方式实现,总感觉怪怪的。

下面是主程序调用该单例方法:


static void Main(string[] args)
   {
     Person p1 = Person.GetSingleton();
     Person p2 = Singleton<Person>.GetSingleton();

if (object.ReferenceEquals(p1, p2))
     {
       Console.WriteLine("两个对象是同一实例");
     }
     Console.ReadKey();
   }

输出结果:

c# 单例模式的实现

来源:https://www.cnblogs.com/jn-shao/p/14318813.html

标签:c#,单例模式
0
投稿

猜你喜欢

  • Spring MVC整合 freemarker及使用方法

    2022-06-06 16:41:41
  • C#简单实现显示中文格式星期几的方法

    2021-09-08 12:27:05
  • Java SpringCache+Redis缓存数据详解

    2023-11-29 01:01:05
  • SpringBoot实现阿里云短信发送的示例代码

    2023-05-15 21:08:54
  • C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    2022-09-14 20:41:14
  • C# 实现FTP客户端的小例子

    2022-06-09 13:19:13
  • java 重载(overload)与重写(override)详解及实例

    2021-06-18 15:59:45
  • Android Studio设置绘制布局时的视图

    2021-09-05 08:15:46
  • Java synchronized锁升级jol过程详解

    2023-04-15 04:58:51
  • Android实现列表数据按名称排序、中英文混合排序

    2022-10-18 15:15:57
  • Java并发编程之原子性-Atomic的使用

    2023-11-09 22:34:58
  • java文件操作输入输出结构详解

    2023-07-30 21:48:30
  • java面试常问的Runnable和Callable的区别

    2023-11-23 09:23:28
  • Android使用系统自带的相机实现一键拍照功能

    2023-06-05 10:27:23
  • java面向对象之人机猜拳小游戏

    2021-12-20 18:12:34
  • java线程中断 interrupt 和 LockSupport解析

    2021-06-29 01:20:48
  • Spring Boot实现图片上传功能

    2023-05-17 05:06:05
  • Java实现XML文件学生通讯录

    2023-07-23 19:21:49
  • Android控件之Gallery用法实例分析

    2021-07-15 06:49:09
  • C#合并多种格式文件为PDF的方法

    2023-12-11 17:46:58
  • asp之家 软件编程 m.aspxhome.com