懒汉式单例:在第一次被引用时才会将自己实例化。
class Singleton
{
private static Singleton instance;
//程序运行时创建一个静态只读的进程辅助对象
private static readonly object syncRoot = new object();
//构造方法让其private,外界就无法使用new创建实例
private Singleton()
{
}
//获得本类实例的唯一全局访问点
public static Singleton GetInstance()
{
/*
* 先判断实例是否存在,不存在再加锁处理。这样不用让线程每次都加锁,而只是在实例未被创建的时候再加锁处理。同时也能保证多线程安全。
* 这种做法被称Double-Check Locking(双重锁定)。
* 两次判断instance==null是因为当同时有两个线程调用GetInstance()方法时,它们将可以通过第一重instance==null的判断,然后由于lock机制,
* 这两个线程则只有一个进入,另一个在外排队等候,必须要其中的一个进入并出来后,另一个才能进入。而此时如果没有了第二重的instance是否为
* null的判断,则第一个线程创建了实例,而第二个线程还是可以继续再创建新的实例,这就没有达到单例的目的。
*/
if (instance == null)
{
//在同一个时刻,只有一个线程可以进入
lock (syncRoot)
{
//若实例不存在,则new一个新的实例,否则返回已有的实例
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
{
private static Singleton instance;
//程序运行时创建一个静态只读的进程辅助对象
private static readonly object syncRoot = new object();
//构造方法让其private,外界就无法使用new创建实例
private Singleton()
{
}
//获得本类实例的唯一全局访问点
public static Singleton GetInstance()
{
/*
* 先判断实例是否存在,不存在再加锁处理。这样不用让线程每次都加锁,而只是在实例未被创建的时候再加锁处理。同时也能保证多线程安全。
* 这种做法被称Double-Check Locking(双重锁定)。
* 两次判断instance==null是因为当同时有两个线程调用GetInstance()方法时,它们将可以通过第一重instance==null的判断,然后由于lock机制,
* 这两个线程则只有一个进入,另一个在外排队等候,必须要其中的一个进入并出来后,另一个才能进入。而此时如果没有了第二重的instance是否为
* null的判断,则第一个线程创建了实例,而第二个线程还是可以继续再创建新的实例,这就没有达到单例的目的。
*/
if (instance == null)
{
//在同一个时刻,只有一个线程可以进入
lock (syncRoot)
{
//若实例不存在,则new一个新的实例,否则返回已有的实例
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
饿汉式代例:自己被加载时就将自己实例化。
/// <summary>
/// 静态初始化方法
/// C#与公共语言运行库也提供了一种‘静态初始化’方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决多线程环境下它是不安全的问题。
/// </summary>
sealed class Singletom2
{
//sealed 阴止发派生,而派生可能会增加实例
//在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化
private static readonly Singletom2 instance = new Singletom2();
private Singletom2() { }
public static Singletom2 GetInstance()
{
return instance;
}
}
/// 静态初始化方法
/// C#与公共语言运行库也提供了一种‘静态初始化’方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决多线程环境下它是不安全的问题。
/// </summary>
sealed class Singletom2
{
//sealed 阴止发派生,而派生可能会增加实例
//在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化
private static readonly Singletom2 instance = new Singletom2();
private Singletom2() { }
public static Singletom2 GetInstance()
{
return instance;
}
}
静态初始化方式提前占用系统资源,懒汉方式面临多线程访问安全性问题。从C#语言角度来讲,饿汉式的单例类已经足够满足我们的需求了。