一、什么是单例模式
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在-一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。
二、单例设计模式的八种方法
- 饿汉式(静态常量)
- 饿汉式(静态代码块)
- 懒汉式(线程不安全)
- 懒汉式(线程安全,同步方法)
- 懒汉式(线程安全,同步代码块)
- 双重检查
- 静态内部类
- 枚举
饿汉式(静态常量)应用实例
代码实现
class Singleton_01
{
//1.构造函数私有化
private Singleton_01()
{
}
//2.本类内部创建对象实例
private static Singleton_01 singleton_01 = new Singleton_01();
//3.提供一个公有静态方法,返回对象实例
public static Singleton_01 getSingleton_01()
{
return singleton_01;
}
}
此时,我们尝试能否通过New的方式创建一个Singleton_01实例。
我们可以看到通过New的方式创建Singleton_01实例报错。
验证是否单例
通过getSingleton_01()方法分别创建两个对象,打印是否相等,以及获取两个对象的HasCode判断两个实例是否相等。
打印True值,以及HasCode一直,证明两个对象为同一个实例。
饿汉式(静态常量)优缺点说明
优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费
懒汉式(线程不安全)
代码实现
public class Singleton_02
{
//声明私有变量
private static Singleton_02 singleton_02;
//构造函数私有化
private Singleton_02()
{
}
//提供一个静态的共有方法,当使用到该方法时,才创建singleton_02
//即懒汉式
public static Singleton_02 GetSingleton_02()
{
if (singleton_02 == null)
{
singleton_02 = new Singleton_02();
}
return singleton_02;
}
}
验证是否为单例
优缺点说明
优点:起到了Lazy Loading效果,只有在用到实例的时候才创建。
缺点:如果在多线程场景下,多个线程同时进入if (singleton_02 == null) 时均为null值,则会创建多个实例,所以说这种方式是线程不安全的,在多线程场景下禁用。
双重检查
我们在懒汉式的基础上加上双重判断和加lock锁解决单例模式的一个线程安全问题
public class Singleton_03
{
//声明私有变量
private static Singleton_03 singleton_03;
//声明锁
private static readonly object _lock = new object();
//构造函数私有化
private Singleton_03()
{
}
//提供一个静态的共有方法,当使用到该方法时,才创建singleton_03
public static Singleton_03 GetSingleton_03()
{
//第一重判断
if (singleton_03 == null)
{
//加锁,保证线程安全
lock (_lock)
{
//第二重判断
if (singleton_03 == null)
{
singleton_03 = new Singleton_03();
}
}
}
return singleton_03;
}
}