单例模式详解
2016-03-07 16:55
190 查看
设计模式——单例模式
创建型设计模式一共包括五类设计模式,分别是:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。上篇博客中讲到了工厂方法模式,这篇博客就给大家说一下经常用到的单例模式。
结构图:
单例模式中就只有这一个类,Singleton类,他的作用是:定义一个GetIntance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。代码如下:
使用单例模式的好处:单例模式因为Singleton封装它的唯一实例,这样它可以严格的控制客户怎样访问它以及何时访问它,简单的说就是对唯一实例的受控访问。
这样可以使得实例对象由最先进入的那个线程创建,以后的线程在进入时不会再去创建对象实例了,由于有了lock,就保证了多线程环境下的同时访问也不会造成多个实例的生成。但是这样的的锁定有一个弊端,就是在每次调用GetInstance时就需要进行一次锁定lock。这样会无形中影响了程序的性能。所以为了解决这个问题,有了下边的双重锁定:
双重锁定不用让线程每次都加锁,而只是在实例未被创建的时候在加锁处理,同时也能保证多线程的安全。代码如下:
为什么叫双重锁定?因为在对于instance存在的情况下,就直接返回,这样就没有问题,当instance为null并且同时有两个线程同时调用GetInstance()方法时,他们将都可以通过第一重instance==null的判断。然后由于lock机制,这两个线程则只有一个进入,另一个在外排队等候。此时如果没有了第二重的instance判断,则第一个线程创建了实例,而第二个线程还是可以在继续创建新的实例的。
单例模式是一个很常见的模式,以后我们在做系统的时候回经常用到,好好总结一下,以后用的时候就知道怎么用了。
创建型设计模式一共包括五类设计模式,分别是:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。上篇博客中讲到了工厂方法模式,这篇博客就给大家说一下经常用到的单例模式。
单例模式:
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。结构图:
单例模式中就只有这一个类,Singleton类,他的作用是:定义一个GetIntance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。代码如下:
class Singleton { private static Singleton instace; private Singleton () { } public static Singleton GetInstance() { if (instace ==null) //判断是否实例化 { instace = new Singleton(); } return instace; } }
使用单例模式的好处:单例模式因为Singleton封装它的唯一实例,这样它可以严格的控制客户怎样访问它以及何时访问它,简单的说就是对唯一实例的受控访问。
多线程的单例:
如果在多线程的程序中,多个线程同时访问Singleton类,调用getInstance方法,会有可能创建多个实例的,所以在这里要在程序中加上一把锁:Lock。Lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区,如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止)直到对象被释放。代码如下:class Singleton { private static Singleton instace; private static readonly object syncRoot = new object(); //程序运行时创建一个静态只读的进程辅助对象。 private Singleton () { } public static Singleton GetInstance() { lock (syncRoot ) //在同一时刻加了锁的那部分程序只有一个线程可以进入。 { if (instace == null) //判断是否实例化 { instace = new Singleton(); } return instace; } } }
这样可以使得实例对象由最先进入的那个线程创建,以后的线程在进入时不会再去创建对象实例了,由于有了lock,就保证了多线程环境下的同时访问也不会造成多个实例的生成。但是这样的的锁定有一个弊端,就是在每次调用GetInstance时就需要进行一次锁定lock。这样会无形中影响了程序的性能。所以为了解决这个问题,有了下边的双重锁定:
双重锁定不用让线程每次都加锁,而只是在实例未被创建的时候在加锁处理,同时也能保证多线程的安全。代码如下:
class Singleton { private static Singleton instace; private static readonly object syncRoot = new object(); //程序运行时创建一个静态只读的进程辅助对象。 private Singleton () { } public static Singleton GetInstance() { if (instace ==null) //第一次判断是否实例化 { lock (syncRoot) //在同一时刻加了锁的那部分程序只有一个线程可以进入。 { if (instace == null) <span style="font-family: Arial, Helvetica, sans-serif;">//第一次判断是否实例化</span> { instace = new Singleton(); } } } return instace; } }<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
为什么叫双重锁定?因为在对于instance存在的情况下,就直接返回,这样就没有问题,当instance为null并且同时有两个线程同时调用GetInstance()方法时,他们将都可以通过第一重instance==null的判断。然后由于lock机制,这两个线程则只有一个进入,另一个在外排队等候。此时如果没有了第二重的instance判断,则第一个线程创建了实例,而第二个线程还是可以在继续创建新的实例的。
单例模式是一个很常见的模式,以后我们在做系统的时候回经常用到,好好总结一下,以后用的时候就知道怎么用了。
相关文章推荐
- QTableWidget 实现整行拖放交换位置
- 单极性PWM和双极性PWM
- 计算机网络面试题
- autolayout 后,怎么获得宽高?
- 从一到无穷大
- BLE协议架构概述(1)
- Codeforces Round #344 (Div. 2) A
- JavaScript之流程语句
- 【Java开发者自学笔记】Java SE 笔记1
- PAT_Basic 1016
- js彩票效果
- 代码的模板化
- JS第8天
- unix more命令
- css样式随记
- 横竖屏切换时候Activity的生命周期的总结
- 目标检测的图像特征提取之(一)HOG特征
- 缓存算法(转载)
- java 判断日期相差几天
- 从win8.1/10第一次使用的欢迎界面的不同看微软转型