单例模式
单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 主要解决:一个全局使用的类频繁地创建与销毁。 何时使用:当您想控制实例数目,节省系统资源的时候。 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。 关键代码:构造函数是私有的。
实现:懒汉式,线程不安全
该实现没有额外开销,不要求线程安全的情况下可以使用:
代码语言:javascript复制public class ApplicationContext
{
private static ApplicationContext instance = null;
private ApplicationContext() { }
public static ApplicationContext Instance
{
get
{
if (instance == null)
{
instance = new ApplicationContext();
}
return instance;
}
}
public string UserId { get; set; }
}
实现:懒汉式,线程安全
由于每次访问单例类实例都会加锁,而加锁是一个非常耗时的操作,故不推荐使用:
代码语言:javascript复制public class ApplicationContext
{
private readonly static object lockObj = new object();
private static ApplicationContext instance = null;
private ApplicationContext() { }
public static ApplicationContext Instance
{
get
{
lock (lockObj)
{
if (instance == null)
{
instance = new ApplicationContext();
}
}
return instance;
}
}
public string UserId { get; set; }
}
实现:懒汉式,双重校验锁
在前面的基础上进行改进,只在第一次创建实例时加锁,提高访问性能:
代码语言:javascript复制public class ApplicationContext
{
private readonly static object lockObj = new object();
private static ApplicationContext instance = null;
private ApplicationContext() { }
public static ApplicationContext Instance
{
get
{
if (instance == null)
{
lock (lockObj)
{
if (instance == null)
{
instance = new ApplicationContext();
}
}
}
return instance;
}
}
public string UserId { get; set; }
}
实现:饿汉式,线程安全
写法简单,线程安全,但构造时机不是由程序员掌控的:
代码语言:javascript复制public class ApplicationContext
{
private static ApplicationContext instance = new ApplicationContext();
private ApplicationContext() { }
public static ApplicationContext Instance
{
get
{
return instance;
}
}
public string UserId { get; set; }
}
不仅如此,假如ApplicationContext
中存在其他静态方法,我去调用的时候就会导致单例构造实例,无法做到访问单例时创建实例
当然,通过内部类实现,可以解决这个问题:
代码语言:javascript复制public class ApplicationContext
{
class Nested
{
internal static readonly ApplicationContext instance = new ApplicationContext();
}
private ApplicationContext() { }
public static ApplicationContext Instance
{
get
{
return Nested.instance;
}
}
public string UserId { get; set; }
}
实现单例基类
代码语言:javascript复制// 由于单例基类不能实例化,故设计为抽象类
public abstract class Singleton<T> where T : class
{
// 这里采用实现5的方案,实际可采用上述任意一种方案
class Nested
{
// 创建模板类实例,参数2设为true表示支持私有构造函数
internal static readonly T instance = Activator.CreateInstance(typeof(T), true) as T;
}
private static T instance = null;
public static T Instance { get { return Nested.instance; } }
}
参考资料
- 《剑指offer》
- http://www.runoob.com/design-pattern/singleton-pattern.html
- https://blog.csdn.net/ycl295644/article/details/46770451