(1)单例模式,从字面意思上理解,“单例”,即只有唯一一个实例,通常情况下,定义一个类,然后通过new ClassName()方式来产生具体对象,然而这样,破坏了一个类只有一个实例,怎么处理该问题呢?将类的具体化放在类的构造函数来完成;
(2)如上方式解决了单例问题,然而,外界如何才能访问该类?很简单,该类提供一个全局的访问点即可;
(3)根据以上(1),(2)步骤的划分,单例模式有2个很明显特点:a.类只有一个实例 b.类必须提供全局唯一的可被访问点
现在个人习惯用的单例模式的写法
public class Singleton2
{
private Singleton2() { }
private static readonly Singleton2 m_Instance = new Singleton2();
public static Singleton2 GetInstance
{
get { return Singleton2.m_Instance; }
}
}
线程安全的写法
public class Singleton
{
// 定义一个静态变量来保存类的实例
private static Singleton m_Instance = new Singleton();
// 定义私有构造函数,使外界不能创建该类实例
private Singleton() { }
// 定义一个标识确保线程同步
private static readonly object locker = new object();
public static Singleton GetInstance()
{
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
// 双重锁定只需要一句判断就可以了
if (m_Instance == null)
{
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (m_Instance == null)
{
m_Instance = new Singleton();
}
}
}
return m_Instance;
}
}
其他还有更多写法,大家也可以参考
第一种(懒汉,线程不安全):
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
第二种(懒汉,线程安全):
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
第三种(饿汉):
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
第四种(饿汉,变种):
public class Singleton {
private Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return this.instance;
}
}
第五种(静态内部类):
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}