满纸荒唐言,一把心酸泪,都云作者痴,谁解其中味。 技术博客 心情随笔
设计模式:单例
2025/4/27 146

导航

1前言

2饿汉模式:不管是否需要都先创建

3懒汉模式:有需要再创建

4总结

1 前言

单例模式是一种高频使用的设计模式,它保证对象始终只有一个,比如为打印机写一个打印控制类,如果这个类能被随意new(),甲new出来一个,乙new出来一个,甲还没打印完成,乙又开始打印,那就乱了套。所以打印控制对象必须唯一,只有一个对象与打印机通讯,当甲乙丙丁同时打印时,在单例对象中实现排队逻辑。单例模式就像美国总统,美国总统只能存在一个,如果有多个,估计全世界人民都会比较高兴。

单例模式具有如下特征:
1、保证一个类仅有一个实例
2、必须自已创建自己的唯一实例
3、提供唯一实例的全局访问点来源:https://www.wubayue.com

2 饿汉模式:不管是否需要都先创建

饿汉模式是实现单例最简单的一种模式,不管是否需要,都先创建出单例对象。它也是典型的空间换时间,让对象常驻内存,从而避免后续使用时的非空判断和创建逻辑,饿汉模式适用于频繁使用的对象。来源:https://www.wubayue.com

// 饿汉模式
public sealed class HungryMan
{
    // 不管是否使用,先创建对象
    private static readonly HungryMan _hungryMan = new HungryMan();

    // 私有构造函数
    private HungryMan() { }

    // 提供全局访问点
    public static HungryMan Instance
    {
        get { return _hungryMan; }
    }
} 

3 懒汉模式:有需要再创建

懒汉模式适用于使用频率低,占用空间大的对象,它在对象在被使用的时候才进行创建。来源:https://www.wubayue.com

// 懒汉模式
public sealed class LazyMan
{
    // volatile关键字指定变量不被编译器优化,以保证在多线程环境中实时同步
    // 以及保证编译时的行顺序不发生变化
    private static volatile LazyMan? _lazyMan = null;
    private static readonly object _syncLock = new Object();

    // 私有构造函数
    private LazyMan() { }

    public static LazyMan Instance
    {
        get
        {
            // 通过双重检查成例(Double Check Idiom)避免锁的滥用
            if (_lazyMan == null)
            {
                lock (_syncLock)
                {
                    if (_lazyMan == null)
                        _lazyMan = new LazyMan();
                }
            }
            return _lazyMan;
        }
    }
} 

4 总结

单例模式本身非常简单,更重要的是需要识别在哪些业务场景中需要使用单例模式。另外在懒汉单例模式中,需要考虑到线程安全,以及锁的效率问题(见代码示例)。来源:https://www.wubayue.com

<全文完>