饿汉懒汉都是好汉——单例模式

来源:互联网 发布:php记录点击次数 编辑:程序博客网 时间:2024/05/01 23:44

前情回顾:

    不知大家是否曾有过类似经历。在做机房收费的时候,单击菜单栏的某个按钮,click 一次便出现一次此窗体,从而导致一个主界面里出现过多相同的窗体,但理想状态是不管如何单击,一个主界面我们只想要某窗体只出现一次。此时,单例模式便可派上大用场。

计划生育,还是一个好:

懒汉单例模式:

    单例模式是相对于众多模式中最严谨守法的好模式。它能保证一个类只有唯一一个对象被实例化,并只提供一个全局访问点。

    具体方法是在需要单例的类中写入私有的构造方法,导致外界不能使用new创建实例。再定义一个访问本类实例的唯一一个全局访问点,从中判断此类有否被实例化过,如果没有,实例化此类。如果已经实例化,则显示已实例化对象。

    具体代码如下:

Class Singleton{Private static Singleton instance;Private Singleton()     //将instance构造方法设定为私有,防止对其无限实例化。{}Public static Singleton GetInstance()//写出一个全局公有的GetInstance方法,来对instance进行判断,最后访问。{If (instance==null){Instance=new Singleton();}Return instance;}}

结构图如下:

多线程时的单例:

1、锁定

    在操作系统概论一书中,详细讲述了线程等概念,在此不再赘述。

    多线程时,同时访问此类调用GetInstance方法,也有可能导致创建出多个实例。可以利用lock锁,让个线程有条不紊的one by one依次进入。

Class Singleton{Private static Singleton instance;Private static readonly object syncRoot=new object()//创建一个进程辅助对象。Private Singleton()     {}Public static Singleton GetInstance()//{Lock (syncRoot)                     //加锁部分,只有一个线程可进入,别的排队等待。{If (instance==null){Instance=new Singleton();}}Return instance;}}

2、双重锁定

    但是这样我们就让线程每次都给加锁,不断的重复。所以可以优化一下,先进行判断,只对没有实例化的时候再加锁处理,防止多个getinstance被调用。这就是传说中的双重锁定。

Double-check lock:

Class Singleton{Private static Singleton instance;Private static readonly object syncRoot=new object()//创建一个进程辅助对象。Private Singleton()     {}Public static Singleton GetInstance()//{If (instance==null)         //先判断,不存在被实例化的instance时,才进行加锁处理。{Lock (syncRoot)                  {If (instance==null){Instance=new Singleton();}}}Return instance;}}

懒汉静态初始化:

    其实严于律己遵守国家规章制度的不只单例一人,还有一位“静态初始化”君。通过一个秘密的sealed关键字达到同样防止多生的效果。

    具体实现如下:

Public sealed class Singleton{Private  static readonly Singleton instance=new Singleton();Pirvate Singleton(){}Public static Singleton GetInstance()\{Return instance;}}

饿汉 vs 懒汉   

     至于饿汉懒汉的称谓主要来源于单例模式要在此一次被引用时,才将自己实例化,相对于静态初始化在自己一被加载的时候就积极实例化而言,表现得懒惰不积极,所以单例模式是个大懒蛋。而静态初始化方法又显得稍微有点太积极主动了,太希望实现自我价值了,早早的就给自己占了个空间。所以被称为饿汉式单例类。不过懒汉饿汉,只要遵纪守法,就是好汉。

0 0
原创粉丝点击