单例模式,就是在程序运行中只能实例化出一个实例,不论在哪里使用这个类就是这同一个实例,也就是说它实例的地址、内容是一样的。
单例模式首先要将类的构造函数私有化,使这个类不能在外部实例化。
然后写一个公共函数,专门实例化这个类 ---- 如果这个类没有实例化过,就实例化一次然后返回这个实例,如果实例化过,就直接返回实例化过的类。
class Singleton
{
private static Singleton instance;
private Singleton()
{ }
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
这正方法在单线程中有效,但是在多线程中,有可能两个或多个线程同时调用这个方法,而之前都没有实例化过,因此在每个线程中它的 instance 就都是 null ,然后就都实例化一次,这样他们实例化出的类就不是同一个实例了,因此在多线程中不能这样写,要同时使用到线程锁。
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;
}
}
class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object();
private Singleton()
{ }
public static Singleton GetInstance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
上面这种方法被称为 懒汉式单例类,因为它是在需要实例的时候才实例化自己。而还有一种 饿汉式单例类 ,它是在加载时就实例化。
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton()
private static readonly object syncRoot = new object();
private Singleton()
{ }
public static Singleton GetInstance()
{
return instance;
}
}
sealed 是为了防止发生派生,而派生可能会增加实例