小谈单例模式
介绍:
说到单例模式,大家第一反应应该就是——什么是单例模式?,从“单例”字面意思上理解为一个类只有一个实例,所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了。
官方定义为:确保一个类只有一个实例,并提供一个全局访问点。
存在的意义:
看完介绍,会不由自主的产生出疑为,为什么要有单例模式?他在什么情况下使用。从官方给出的定义我们可以得出,该类在系统中只可以被实例一次,所有在系统中某个对象只需要实例一次,要保证全局唯一。多操作时也是只对单一实例修改。保证结果的统一性。
单例模式的实现原理:
了解了一些基础,知道单例模式是什么用来干什么之后我们就想知道怎么实现单例,不要急,我们慢慢来。
首先我们通过定义可以知道两点:
(1) 确保只有一个实例
(2) 提供一个全局访问点
通常我们创建实例都是通过关键字new 来实现创建的,但是我们为了保证单个实例,不允许此类被重复创建,很明显不能继续直接使用new关键字创建。所有我们需要把构造函数定义为私有类型。然后给出全局访问点(也就是一个静态方法)。请看下面代码【经典模式】:
1 public class Singleton 2 { 3 private static Singleton instance; 4 5 private Singleton() 6 { 7 8 } 9 10 public static Singleton GetInstance() 11 { 12 if(instance==null) 13 { 14 instance=new Singleton(); 15 } 16 return instance; 17 } 18 }
注释翻译:
1) 构造函数为私有,保证了不会被重复new 实例,达到单例的目的。
2) 提供了一个静态方法,此方法验证该类是否为空,非空则返回,达到了不重复创建。再次验证变量要是静态。
以上就是实现的单例,看似完整,其实不然,在单线程下是对的,但是在多线程下可以同时多个通过验证,所有次方法在多线程下是不安全的。为了达到多线程也实现单例的目的,我们采用加锁的方式,让验证再次执行我们所赋予他的使命!
多线程下的单例(Lazy模式):
1 public class Singleton 2 { 3 private static Singleton instance; 4 private static object _lock=new object(); 5 6 private Singleton() 7 { 8 9 } 10 11 public static Singleton GetInstance() 12 { 13 if(instance==null) 14 { 15 lock(_lock) 16 { 17 if(instance==null) 18 { 19 instance=new Singleton(); 20 } 21 } 22 } 23 return instance; 24 } 25 }
注释翻译:
1) 定义加锁变量,用来对多线程进行加锁,保证对该单例线程创建线程的唯一。保证了同时只有一条线程可以进入创建。
2) 两次instance==null 是为了优化性能。在已经创建成功实例后多线程不需要在加锁条件下等待。
多线程下的单例(恶汉模式):
自己创建,使用者只需调用全局方法使用即可。
public sealed class Singleton { private static readonly Singleton instance=new Singleton(); private Singleton() { } public static Singleton GetInstance() { return instance; } }
代码是把创建实例交给crl,我们都知道静态构造函数只会创建一次,并且由clr自动创建,所有这个模式我们不需要考虑线程安全。
最后:单例模式只是为了创建单一实例而形成的模式,保证的只是当前示例类的唯一,不是数据的唯一,同样示例的方法和变量在多线程下,仍然可能不安全。模式只是总结的方法。
作者:YanBigFeg —— 颜秉锋
出处:http://www.cnblogs.com/yanbigfeg
本文版权归作者和博客园共有,欢迎转载,转载请标明出处。如果您觉得本篇博文对您有所收获,觉得小弟还算用心,请点击右下角的 [推荐],谢谢!