保证一个类仅有一个实例,,并提供一个访问它的全局访问点
-
//懒汉式
-
class Singleton
-
{
-
private static Singleton instance;
-
-
private Singleton()
-
{}
-
-
public static Singleton GetInstance()
-
{
-
if (NULL == instance)
-
{
-
instance = new Singleton();
-
}
-
-
return instance;
-
}
-
};
多线程时的单例模式:
所有类的基类——Object
-
//多线程情况下:
-
class Singleton
-
{
-
private static Singleton instance;
-
//加一个锁
-
private static readonly object sync = new object();
-
-
private Singleton()
-
{}
-
-
public static Singleton GetInstance()
-
{
-
if (NULL == instance) //先判断是否存在,不存在再竞争
-
//之所以要这样,是为了防止每次调用都要涉及到锁,毕竟只实例化一次
-
{
-
lock(sync)
-
{
-
if (NULL == instance)
-
{
-
instance = new Singleton();
-
}
-
}
-
}
-
return instance;
-
}
-
};
单例模式分两类
一、在自己被加载时就将自己实例化,称为饿汉式单例类
类一加载就实例化对象,提前占用系统资源
-
//饿汉式
-
public sealed class Singleton
-
{
-
private static readonly Singleton instance = new Singleton();
-
private Singleton()
-
{}
-
-
public static Singleton GetInstance()
-
{
-
return instance;
-
}
-
};
二、在第一次被引用时才将自己实例化,称为懒汉式单例类
面临多线程访问的安全性问题, 即第一个程序那样
你只要弄明白单例模式是如何实现的,就能从本质上理解这个问题; 单例模式实现过程如下: 首先,将该类的构造函数私有化(目的是禁止其他程序创建该类的对象); 其次,在本类中自定义一个对象(既然禁止其他程序创建该类的对象,就要自己创建一个供程序使用,否则类就没法用,更不是单例); 最后,提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。 直白的讲就是,你不能用该类在其他地方创建对象,而是通过该类自身提供的方法访问类中的那个自定义对象。 那么问题的关键来了,程序调用类中方法只有两种方式,①创建类的一个对象,用该对象去调用类中方法;②使用类名直接调用类中方法,格式“类名.方法名()”; 上面说了,构造函数私有化后第一种情况就不能用,只能使用第二种方法。 而使用类名直接调用类中方法,类中方法必须是静态的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的。 这就是单例模式唯一实例必须设置为静态的原因。