C#单例模式使用
2016-04-14 19:35
204 查看
1、什么是单例
单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,通过上图我们知道它包含的角色只有一个,就是Singleton,它拥有一个私有构造函数,这确保用户无法通过new直接实例它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()方法负责检验并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。作用:单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。
2、三种写法
[b]2.1.经典模式:[/b]public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton GetInstance() { if(instance==null) { instance=new Singleton(); } return instance; } }
在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。
[b]2.2 多线程下的单例模式[/b]
public class Singleton { private static Singleton instance; private static object _lock=new object(); private Singleton() { } public static Singleton GetInstance() { if(instance==null) { lock(_lock) { if(instance==null) { instance=new Singleton(); } } } return instance; } }
上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。
[b]2.3 饿汉模式[/b]
public sealed class Singleton { private static readonly Singleton instance=new Singleton(); private Singleton() { } public static Singleton GetInstance() { return instance; } }
上面使用的readonly关键可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。
3、单例模式的优点
单例模式(Singleton)会控制其实例对象的数量,从而确保访问对象的唯一性。实例控制:单例模式防止其它对象对自己的实例化,确保所有的对象都访问一个实例。
伸缩性:因为由类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
4、单例模式的缺点:
系统开销。虽然这个系统开销看起来很小,但是每次引用这个类实例的时候都要进行实例是否存在的检查。这个问题可以通过静态实例来解决。开发混淆。当使用一个单例模式的对象的时候(特别是定义在类库中的),开发人员必须要记住不能使用new关键字来实例化对象。因为开发者看不到在类库中的源代码,所以当他们发现不能实例化一个类的时候会很惊讶。
对象生命周期。单例模式没有提出对象的销毁。在提供内存管理的开发语言(比如,基于.NetFramework的语言)中,只有单例模式对象自己才能将对象实例销毁,因为只有它拥有对实例的引用。在各种开发语言中,比如C++,其它类可以销毁对象实例,但是这么做将导致单例类内部的指针指向不明。
5、单例适用性
使用Singleton模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式。反之,如果一个类可以有几个实例共存,就不要使用单例模式。不要使用单例模式存取全局变量。这违背了单例模式的用意,最好放到对应类的静态成员中。
不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放,带来问题。
参考:
/article/5414550.html
/article/4938542.html
相关文章推荐
- C#实现优先队列 基于二叉堆 附使用案例
- C# 使用Tuple传递多个参数
- C# Interlocked 笔记
- C# Timer类详解
- C# get
- C# 单例模式的不同写法对静态变量的影响
- c#XML配置文件辅助类
- C# Socket SSL通讯笔记
- C# DataTable添加行和列
- C# 数组与 list 互相转换案例
- c#概念理解
- 适用于WebForm Mvc的Pager分页组件C#实现
- C#委托与事件的本质区别
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
- c#中的保留两位小数并且四舍五入
- C#解析错误代码至错误提示字符串
- C# WinForm 技巧:控件截图
- C#第6周实验类的继承
- C# Dictionary使用
- [C#]exchange发送,收件箱操作类