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

本文深入探讨了单例模式的实现方式,包括懒汉单例、多线程时的单例处理、静态初始化等,通过实例代码解释了每个模式的特点与应用。

前情回顾:

    不知大家是否曾有过类似经历。在做机房收费的时候,单击菜单栏的某个按钮,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 懒汉   

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

评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值