博客
关于我
初夏小谈:设计模式之单例模式
阅读量:786 次
发布时间:2019-03-25

本文共 2093 字,大约阅读时间需要 6 分钟。

设计模式入门:探索单例模式与饿汉模式

设计模式是软件开发中反复使用的代码经验总结,它让代码更具可维护性和可扩展性。在本文中,我们探讨单例模式及其两种实现形式:饿汉模式和懒汉模式。

单例模式概述

单例模式是指在一个类中只能创建一个对象。这种设计思想确保了类独有的对象,使得资源管理更加高效,尤其在多线程环境下。单例模式通常提供了全局访问点,使得程序只需调用该点即可获得唯一的对象。

单例模式主要包含两种实现方式:饿汉模式和懒汉模式。这两种模式在设计单例对象时有不同的实现策略。以下将从饿汉模式开始深入探讨。


饿汉模式: 自始至终

饿汉模式的核心思想是“一旦启动程序,就立即创建对象”。无论是否需要这个对象,它都会在程序启动时就创建完成。这种方法节省了每次使用时因资源竞争带来的开销,尤其在频繁使用的多线程环境中非常高效。

饿汉模式的实现特点

  • 对象在程序启动时自发性地创建

    通过使用 static 关键字,确保对象在类加载时就被创建。

  • 防止类外构造对象

    通过私有化构造函数和拷贝构造函数,阻止类外直接创建对象。

  • 全局访问接口

    提供一个静态方法供外部获取该唯一对象,避免了对对象的直接访问操作。

  • 饿汉模式代码示例

    class Singleton {public:    static Singleton& GetSingleton() {        return Singleton::Object;    }private:    Singleton() {}    Singleton(const Singleton& s) {}    static Singleton Object;};Singleton Singleton::Object;

    饿汉模式的优点

    • 简化了资源管理:无需在其他地方管理对象生命周期。-避免资源竞争:在多线程环境下,直接获取全局对象,消除了竞争风险。

    懒汉模式: 懒得不能带

    懒汉模式则完全相反——在第一次需要使用对象时,程序才创建它。这种方式可以节省内存资源,尤其在对象频繁被使用的场景中。但由于其延迟初始化特性,也可能带来其他问题。

    懒汉模式的实现特点

  • 不在程序启动时创建对象

    通过检查对象状态,在需要时才进行创建。

  • 使用静态指针并加锁

    解决多线程环境中的竞态问题,确保对象只能由一个线程创建。

  • 延迟释放对象

    在程序退出时,确保最后一个使用该对象的线程完成后,及时释放内存。

  • 懒汉模式代码示例

    class Singleton {public:    static Singleton* GetObject() {        if (Singleton::object == nullptr) {            Mutex.lock();            if (Singleton::object == nullptr) {                Singleton::object = new Singleton();            }            Mutex.unlock();        }        return Singleton::object;    }    ~Singleton();    static Singleton* volatile object;    static Mutex Mutex;    static Clear clear;};Singleton* volatile Singleton::object = nullptr;Mutex Singleton::Mutex;Singleton::Clear Singleton::clear;

    懒汉模式的优点

    • 内存占用最优:只有在需要时才占用内存资源。
    • 线程安全:通过锁机制和双重检测,确保多线程环境下的安全性。
    • 延迟初始化:避免了不必要的对象创建开销。

    饮食模式(多线程下的懒汉模式)

    在单线程环境下,懒汉模式的实现较为简单。但在多线程环境中,可能会遇到如下问题:

  • 竞态问题

    如果在创建对象的同时,另一个线程试图调用该方法,可能会导致对象被创建多次。为此,需要使用锁机制。

  • 双检测问题

    临行时,由于编译器指令重排,可能导致在第一个对象创建时,其他线程仍然遇到未初始化对象的问题。为了解决,通常采用双重检测(先加锁,再检查一遍)。

  • 内存释放问题

    需要确保在最后一个线程调用完对象后,及时释放内存资源。

  • 解决方法

    为解决多线程环境下的懒汉模式问题,设计需要以下机制:

  • 加锁:确保只有一个线程可以执行对象创建逻辑。
  • 双检测:避免由于指令重排带来的潜在问题。
  • 延迟释放:在对象最后一次使用后,通过内部清理机制释放内存资源。
  • 关闭时自动清理:在程序退出时,确保所有动态内存被释放。

  • 通过上述分析,我们可以清晰地看到,选择-between-`饿汉模式和懒汉模式取决于具体应用场景和性能需求。在单线程环境中,饿汉模式可能更简单易于实现,而在多线程、高并发场景下,懒汉模式通过锁机制和双重检测,能够更好地处理资源竞争问题。

    转载地址:http://vncuk.baihongyu.com/

    你可能感兴趣的文章
    postgres--流复制
    查看>>
    postgres10配置huge_pages
    查看>>
    PostgreSQL 10.0 preview sharding增强 - pushdown 增强
    查看>>
    PostgreSQL 10.0 preview 变化 - pg_xlog,pg_clog,pg_log目录更名为pg_wal,pg_xact,log
    查看>>
    PostgreSQL 10.1 手册_部分 II. SQL 语言_第 15章 并行查询_15.2. 何时会用到并行查询?...
    查看>>
    PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.23. 行和数组比较
    查看>>
    PostgreSQL 10.1 手册_部分 III. 服务器管理_第 21 章 数据库角色
    查看>>
    Qt开发——网络编程UDP网络广播软件之服务器端
    查看>>
    Postgresql 12.9如何配置允许远程连接
    查看>>
    PostgreSQL 9.6 同步多副本 与 remote_apply事务同步级别 应用场景分析
    查看>>
    Postgresql CopyManager 流式批量数据入库
    查看>>
    PostgreSQL cube 插件 - 多维空间对象
    查看>>
    PostgreSQL Daily Maintenance - cluster table
    查看>>
    PostgreSQL on Linux 最佳部署手册
    查看>>
    PostgreSQL Oracle 兼容性之 - pipelined
    查看>>
    PostgreSQL Point-In-Time Recovery (Incremental Backup)
    查看>>
    postgresql Streaming Replication监控与注意事项
    查看>>
    postgresql 不需要付费_使用数据传输在PostgreSQL执行 外部连接运算符
    查看>>
    postgresql 主从配置_生产环境postgresql主从环境配置
    查看>>
    postgresql 函数&存储过程 ; 递归查询
    查看>>