博客
关于我
初夏小谈:设计模式之单例模式
阅读量: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/

    你可能感兴趣的文章
    Mysql8.0的特性
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>
    MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
    查看>>
    Mysql: 对换(替换)两条记录的同一个字段值
    查看>>
    mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
    查看>>
    MYSQL:基础——3N范式的表结构设计
    查看>>
    MYSQL:基础——触发器
    查看>>
    Mysql:连接报错“closing inbound before receiving peer‘s close_notify”
    查看>>
    mysqlbinlog报错unknown variable ‘default-character-set=utf8mb4‘
    查看>>
    mysqldump 参数--lock-tables浅析
    查看>>
    mysqldump 导出中文乱码
    查看>>
    mysqldump 导出数据库中每张表的前n条
    查看>>
    mysqldump: Got error: 1044: Access denied for user ‘xx’@’xx’ to database ‘xx’ when using LOCK TABLES
    查看>>
    Mysqldump参数大全(参数来源于mysql5.5.19源码)
    查看>>