单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。
通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
单例模式结构图:
Singleton类,定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。
class Singleton
{
private static Singleton instance;
//构造方法让其private,这就堵死了外界利用new 创建此类实例的可能
private Singleton()
{
}
public static Singleton GetInstance()
{
if(instance == null)
{
instance = new Singleton();
}
return instance;
}
}
---客户端代码---
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if(s1==s2)
{
Console.WriteLine("两个对象是相同的实例");
}
Console.Read();
}
以上创建单例的代码在多线程环境下会有问题,如果要保证在多线程运行下也是唯一则如下:
class Singleton
{
private static Singleton instance;
//程序运行时创建一个静态只读的进程辅助对象
private static readonly object syncRoot = new object();
//构造方法让其private,这就堵死了外界利用new 创建此类实例的可能
private Singleton()
{
}
public static Singleton GetInstance()
{
//双重锁定,先判断,不存在则锁,再判断
if(instance == null)
{
lock(syncRoot)
{
if(instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
在实际应用当中,c#与公共语言运行库也提供了一种‘静态初始化'方法,这种方法不需要开发人员显式地编写安全代码,即可解决多线程环境下不安全的问题
代码
//sealed 阻止发生派生,而派生可能会增加实例
public sealed class Singleton
{
//在第一次引用类的任何成员时创建实例,公共语言运行库负责处理变量的初始化
private static readonly Singleton instance = new Singleton();
private Singleton()
{}
public static Singleton GetInstance()
{
return instance;
}
}
这种静态初始化的方式是在自己被加载时就将自己实例化验,所以被形象地称之为饿汉式单例类(注:要提前占用资源哦),原先的单例模式处理方式是要在第一次被引用时,才将自己实例化,所以称为懒汉式单例类。