单例模式是设计模式中最简单的一种,主要目的就是确保程序运行期间只有一个对象被创建。
特点:构造函数私【私有】、类内部有【私有】自身类型的属性、提供获取实例的静【静态】方法;
好处是大大减少了对象创建时的性能损耗和内存占用;
单例模式的创建方式有 懒汉模式、饿汉模式、双重锁模式、静态内部类单例模式、枚举单例模式
1、懒汉模式:
/// <summary>
/// 懒汉单例
/// </summary>
public class SingletonLH {
/// <summary>
/// 私有的自身类型的属性
/// </summary>
private static SingletonLH singletonLH;
/// <summary>
/// 私有构造函数
/// </summary>
private SingletonLH(){}
/// <summary>
/// 获取对象的静态方法
/// </summary>
/// <returns></returns>
public static SingletonLH GetSingletonLH() {
if (singletonLH is null)
singletonLH = new SingletonLH();
return singletonLH;
}
}
缺点:线程不安全、延迟初始化,严格意义上不算是单例模式,基本上不会有人用
2、饿汉模式
/// <summary>
/// 饿汉单例
/// </summary>
public class SingletonEH
{
/// <summary>
/// 私有的自身类型的属性
/// </summary>
private static SingletonEH singletonEH = new SingletonEH();
/// <summary>
/// 私有构造函数
/// </summary>
private SingletonEH(){}
/// <summary>
/// 获取对象的静态方法
/// </summary>
/// <returns></returns>
public static SingletonEH GetSingletonLH()
{
return singletonEH;
}
}
好处:线程安全,只初始化一次、内存中仅留存一份,不会被拷贝
坏处:程序开始的时候就初始化,如果一直不用会存在内存浪费,占用资源
3、双重锁模式
/// <summary>
/// 双重锁单例模式
/// </summary>
public class SingletonSCS
{
/// <summary>
/// 私有的自身类型的属性
/// </summary>
private volatile static SingletonSCS singletonSCS;
/// <summary>
/// 锁
/// </summary>
private static readonly object _lockSCS = new object();
/// <summary>
/// 私有构造函数
/// </summary>
private SingletonSCS() { }
/// <summary>
/// 获取对象的静态方法
/// </summary>
/// <returns></returns>
public static SingletonSCS GetSingletonLH()
{
//第一次判断
if (singletonSCS is null)
{
//加锁
lock(_lockSCS) {
//第二次判断
if (singletonSCS is null)
singletonSCS = new SingletonSCS();
}
}
return singletonSCS;
}
}
好处:线程安全,延迟初始化,使用Volatile声明的变量就相当于告诉编译器,我不要把这个变量写Cache,因为这个变量是可能发生改变的。
4、静态内部类单例模式
/// <summary>
/// 静态内部类单例模式
/// </summary>
public class SingletonJTNBL
{
/// <summary>
/// 私有构造函数
/// </summary>
private SingletonJTNBL() { }
/// <summary>
/// 获取对象的静态方法
/// </summary>
/// <returns></returns>
public static SingletonJTNBL GetSingleton() {
return innerClass.singletonJTNBL;
}
/// <summary>
/// 一个静态内部类提供一个静态的实例
/// </summary>
private static class innerClass{
public static SingletonJTNBL singletonJTNBL = new SingletonJTNBL();
}
}
好处:保证了对象的唯一性,是目前最为推荐的单例模式
5、枚举单例模式
c# 不支持这种写法,在c#中枚举是一个值类型,内部不存在方法一说
ps:针对大对象可使用Lazy<>进行延迟加载。
2019年10月22日23:20:03
往后三个星期,每天复习一个设计模式,Go