C#单例模式之懒汉 / 饿汉
2021-07-15 18:18
标签:protected img 通过 操作 直接 任务 贵的 不能 软件
在使用某个设计模式之前必须先了解使用它的优点:
1、单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例对象,减少了对象的创建,从而减轻了程序内存的开销。
2、单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
3、说白了就是保证一个类仅有一个实例,并提供一个该实例的全局访问点。
应用场景:
1. Windows的Task Manager(任务管理器)就是很典型的单例模式,任何时候只能打开一个窗口。
2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
3. 网站的计数器,一般也是采用单例模式实现,否则难以同步。
4. 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
5. Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
6. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
7. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
8. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
代码实现(懒汉模式:在第一次被引用时将自己实例化):
1.将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;(防止调用者直接实例化)
2.在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。
3.创建访问者对象(用于加锁防止并发)
4.创建全局访问点(输出实例):所以该方法绝对不能是 private、protected不然其他类无法调用该方法,并且必须是静态的方法因为 本类构造函数为
私有的外部无法实例化本类(前面已经讲了),所以只能通过 类名 .(点) 方法名来调用该方法。不然你在创建的这个类就是废类别人无法使用
使用双重锁来防止多线程调用出现的并发问题:
当Single为null并且同时有两个线程调用
GetInstance方法时,他们将都可以通过第
一重Single==null的判断,然后由于lock
机制,这两个线程则只有一个进入,另一
个在外排队等候,必须要其中的一个进入
并出来后,另一个才能进入。而此时如果
没有了第二重的Single是否为null的判断,
则第一个线程创建了实例,而第二个线程
还是可以继续在创建新的实例,这就没有
达到单例的目的。
5.调用
(饿汉模式:加载时就将自己实例化)
注意:此时服务对象已经在程序加载时赋值为该类实例(但是只赋值一次,因为 static readonly是使用静态构造函数赋值)
这样的实现与前面的示例类似,也是解决了单例模式视图解决的两个基本问题:全局访问和实例化控制,公共静态属性为访问实例提供了一个全局访问点。不同之处在于它依赖公共语言运行库来初始化变量。由于构造方法是私有的,因此不能再类本身以外实例化Singleton类;因此,变量引用的是可以在系统中存在的唯一的实例。不过要注意,instance变量标记为readonly,这意味着只能在静态初始化期间或在构造函数中分配变量。由于这种静态初始化的方式是在自己被加载时就将自己实例化,所以被形象的称之为饿汉式单例类,原先的单例模式处理方式是要在第一次被引用时,才会将自己实例化,所以就称为懒汉式单例类。
由于饿汉式,即静态初始化的方式,它是类一加载就实例化的对象,所以要提前占用系统资源。然后懒汉式,又会面临着多线程访问的安全性问题,需要做双重锁定这样的处理才可以保证安全。所以到底使用哪一种方式,取决于实际的需求。从C#语言角度来讲,饿汉式的单例类已经足够满足我们的需求了。
C#单例模式之懒汉 / 饿汉
标签:protected img 通过 操作 直接 任务 贵的 不能 软件
原文地址:https://www.cnblogs.com/LaoWang666/p/8921057.html