学习设计模式,必然会谈到单例模式,由于它是一种很经常使用的软件设计模式,本节开始学习单例模式,首先解释单例模式的定义、分类,接着实例介绍饿汉式单例模式类、懒汉式单例模式类、在多线程中的应用及它们的区别,最后列举一个单例模式的实例,以供参考。设计模式
定义:安全
单例模式:保证一个类仅有一个实例,并提供一个全局访问点。服务器
相关解释:在应用单例模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只须要拥有一个的全局对象,这样有利于咱们协调系统总体的行为。好比在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,而后服务进程中的其余对象再经过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。多线程
单例模式通常分为两大类:函数
一、饿汉式单例:静态初始化的方式是在本身被加载时就将本身实例化;学习
二、懒汉式单例:在第一次被引用时,才会将本身实例化。this
实现:spa
实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个得到该实例的方法(必须是静态方法,一般使用getInstance这个名称);当咱们调用这个方法时,若是类持有的引用不为空就返回这个引用,若是类保持的引用为空就建立该类的实例并将实例的引用赋予该类保持的引用;同时咱们还将该类的构造函数定义为私有方法,这样其余处的代码就没法经过调用该类的构造函数来实例化该类的对象,只有经过该类提供的静态方法来获得该类的惟一实例。线程
饿汉式单例模式类: 设计
//饿汉式 class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton GetInstance() { return instance; } }
懒汉式单例模式类:
//懒汉式 class Singleton { private static Singleton instance; private Singleton() { } public static Singleton GetInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
在多线程中应用:
在多线程的应用场合下必须当心使用。若是当惟一实例还没有建立时,有两个线程同时调用建立方法,那么它们同时没有检测到惟一实例的存在,从而同时各自建立了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例惟一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会下降效率)。
代码实例:
class Singleton { private static Singleton instance; private static readonly object obj = new object(); private Singleton() { } public static Singleton GetInstance() { if (instance == null) { lock (obj) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
饿汉式和懒汉式区别:
饿汉式,即静态初始化式,它是在类第一次加载就实例化的对象,因此须要提早占用系统资源。
懒汉式:虽然不会有饿汉式的问题,可是它会面临着多线程访问的安全性问题,须要作双重锁定的处理才能保证系统安全,一样会下降效率。
具体如何使用,就须要取决育实际,没有谁好谁劣。
实例:
列举一个完整的例子,谨供参考。功能:新建一个Form1窗体,Form1窗体中有一个button控件,弹出一个FormToolbox窗体。要求:每次只能弹出一个FormToolbox窗体,只有在关闭FormToolbox窗体时才容许系统从新弹出新的FormToolbox窗体。
贴代码:
//Form1窗体: private void Form1_Load(object sender, EventArgs e) { this.IsMdiContainer = true; } private void button1_Click(object sender, EventArgs e) { FormToolbox.GetInstance().Show(); } //FormToolbox窗体: 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; } }
到此,单例模式讲解完毕。
补充:
正如一位园友fsllsf所说,还有一种方式:
C#与公共语言运行库提供了一种“静态初始化”方法,这种方法不须要开发人员显式地编写线程安全代码,便可解决多线程环境下它是不安全的问题。
public sealed class Singleton { private static readonly Singleton instance = new Singleton(); private Singleton() { } public static Singleton GetInstance() { return instance; } }