小谈单例模式

介绍:

说到单例模式,大家第一反应应该就是——什么是单例模式?,从“单例”字面意思上理解为一个类只有一个实例,所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了。

官方定义为:确保一个类只有一个实例,并提供一个全局访问点。

存在的意义:

看完介绍,会不由自主的产生出疑为,为什么要有单例模式?他在什么情况下使用。从官方给出的定义我们可以得出,该类在系统中只可以被实例一次,所有在系统中某个对象只需要实例一次,要保证全局唯一。多操作时也是只对单一实例修改。保证结果的统一性。

单例模式的实现原理:

  了解了一些基础,知道单例模式是什么用来干什么之后我们就想知道怎么实现单例,不要急,我们慢慢来。

   首先我们通过定义可以知道两点:

(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自动创建,所有这个模式我们不需要考虑线程安全。

最后:单例模式只是为了创建单一实例而形成的模式,保证的只是当前示例类的唯一,不是数据的唯一,同样示例的方法和变量在多线程下,仍然可能不安全。模式只是总结的方法。

posted @ 2017-04-08 10:58  YanBigFeg  阅读(208)  评论(0编辑  收藏  举报