概念:
单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。
简单说明:
有些类我们实例化只需要实例出一个就好了,比如说那些表示状态的窗口。如果同时实例化出多个,但是显示的又不一样,那么到底哪个是对的就不清楚了。所以这个模式可以保证一个类仅有一个实例。
单例模式实现:
工具箱类(用来调用的)
public partial class FormToolbox : Form
{
//定义一个全局变量,用来判断是否实例化过
private static FormToolbox ftb = null;
//定义一个私有的构造函数,在其它地方无法直接实例化
private FormToolbox ()
{
InitializeComponent();
}
//定义一个方法,用来在其它地方可以调用
public static FormToolbox GetInstance()
{
//用来判断是否应该生成一个实例
if (ftb == null || ftb.IsDisposed )
{
ftb = new FormToolbox();
ftb.MdiParent = Form1.ActiveForm;
}
return ftb;
}
}
窗体类(用来显示工具箱的)
private void ToolStripMenuItemToolbox_Click_1(object sender, EventArgs e)
{
FormToolbox .GetInstance ().Show ();
}
这个就是在父窗体上点击生成一个工具箱窗体的代码,很简单。要求只能生成一个工具箱。
双重锁定:
这里涉及到一个多线程访问的问题,就是同时有两个线程访问,但是通过判断当时都没有实例的生成,所以两个线程都生成了实例,也就违背了我们当初的设计。
所以我们采取双重锁定的方式来解决多线程访问的问题。通过第一步判断是否生成实例来决定之后大量的代码是否生成,如果没有实例恰巧又是多线程访问,那么最快进入的那个线程给它加锁,在锁里面继续判断是否生成了实例,因为后面排队进入锁的线程都等着生成呢,所以只要第一个加锁生成了实例之后,及时后面的进入了锁也都无效了。
private static Singleton instance;
private static readonly object synRoot = new object();
private Singleton ()
{
}
public static Singleton GetInstance()
{
if (instance==null)
lock(syncRoot)
{
if (instancen==null)
{
instance =new Singleton();
}
}
}
}
饿汉懒汉:
饿汉指的是该段代码在被加载的时候就生成一个实例,好处是不用考虑多线程,因为人家早就有了一个,坏处是占用资源;
懒汉指的是第一次引用才实例化,好处是平常不占资源,坏处是还得解决多线程问题。
生活感想:
继续用吃东西吧。。。
我喜欢吃冰激凌,可以妈妈每天只允许我吃一个。开始的时候,我是自己想着今天有没有吃,然后让妈妈送进来一个,但是我有怎么能忍住呢,每天吃好多。最后妈妈发现了,再也不相信我了,每天拿没拿她开始留心。——结局是每天只能吃一个。。。
斗智斗勇的故事怎能就这样结束
我和弟弟在妈妈的铁血管制下,每天竟然只能有一个人吃一个。。。但是,聪明的中国人怎能就此屈服,我去要冰激凌,妈妈一看冰箱,发现今天没人吃,然后答应了我,就在这时,弟弟也来要,问妈妈今天有人吃了吗,妈妈说没有,然后也答应了弟弟,最后,我拿了一个,弟弟也拿了一个~~
最后又让妈妈发现了,答应的时候想一下,拿冰激凌的时候又想一下——结局是我们邪恶的计划破产了。。
——本学习总结参考书籍为《大话设计模式》作者:程杰