1、基本概念
Ensure a class has only one intance,and provide a global point of access to it.
确保只有一个实例,而且自行实例化并向整个系统提供这个这个实例。
- 单例类只能有一个实例;
- 单例类必须自己创建自己的唯一单例
- 单例类必须给所有其他对象提供这一实例。
2、核心代码
将构造函数设为私有的,获取实例的属性(或方法)为静态的。
3、应用和优点
- 如果一个对象需要频繁的创建、销毁时,使用单例能减少内存消耗;
- 如果一个对象的产生需要比较多的资源时,如配置文件、产生其他依赖对象,使用单例模式可以优化系统性能,并减少内存开销;
- 写文件时,为了避免对同一个资源文件的同时操作,可以使用单例模式规避对资源的多重占用;
- 单例模式可以设置全局访问点,优化和共享资源访问。
4、代码实现
(1) 普通懒汉模式(加载时不会实例化,调用时才实例化)
public class LazySingleton
{
//私有构造函数
private LazySingleton()
{
}
private static LazySingleton _singletonInstance;
public static LazySingleton GetSingletonInstance()
{
if (_singletonInstance == null) //并发无法保证单例
{
_singletonInstance = new LazySingleton();
}
return _singletonInstance;
}
}
(2)懒汉模式加锁双重判断保证线程安全
注意:在高并发的情况下,需要注意单例模式的线程同步问题。(高并发有可能会产生多个实例)
C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问。他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作,防止出现对象被多次改变情况。
public class LazySingleton
{
//私有构造函数
private LazySingleton()
{
}
private static LazySingleton _singletonInstance;
private static readonly object locker = new object();
public static LazySingleton SingletonInstance
{
get
{
//第一次调用才需要加锁,避免性能浪费
if (_singletonInstance == null)
{
lock (locker) //给临界区加锁排队
{
if (_singletonInstance == null)
{
_singletonInstance = new LazySingleton();
}
}
}
return _singletonInstance;
}
}
}
(3)饿汉模式(第一次加载时实例化)
public class HungrySingleton
{
private HungrySingleton()
{
}
//第一次加载时实例化
private static readonly HungrySingleton _singletonInstance = new HungrySingleton();
public static HungrySingleton SingletonInstance
{
get
{
return _singletonInstance;
}
}
}