ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单例模式 (Singleton Pattern)

2021-05-09 15:02:29  阅读:207  来源: 互联网

标签:Singleton getInstance Pattern 实例 Gc 单例 线程 unique


是什么,有什么用

一个类需要保证全局最多同时存在一个实例

有些东西需要保证全局只有一个,例如线程池、缓存、对话框。。。

要点

两种方法

  1. 懒汉式
    • 等到第一次实用的时候才实例化第一个实例
  2. 饿汉式
    • 加载类的时候就实例化第一个实例,之后都是调用
    • 缺点 - 没用到该类的时候就会占用系统资源(花时间实例化,占用系统空间),如果占用空间不大或者业务不在乎系统资源的话,可以使用
    • 优点 - 无线程安全问题

线程安全问题(仅针对懒汉式

实例化的时候,如果是多线程环境可能存在实例化多次的情况。

java可以通过 synchronized 或者 双重检验锁 的方法来解决

内存安全

防止内存泄漏

CPP实现

实现单例模式,需要

  1. 一个类静态变量,代表现在的状态,即现在是否存在单例
  2. 把构造函数放入private中,防止外部胡乱调用
  3. public中加入getInstance函数,以获取单例
    • 如果没实例,实例化一个
    • 返回唯一的实例

懒汉式(线程不安全)

  1. 线程安全问题
  2. 内存泄漏问题
// code1.
// .h
class Singleton{
private:
    static Singleton *unique;
    Singleton();
public:
    static Singleton *getInstance();
};

// .cpp
Singleton* Singleton::unique = nullptr; // 不写会寄
Singleton::Singleton(){};
Singleton* Singleton::getInstance(){
    if(unique ==nullptr)
        unique = new Singleton();
    return unique;
}

懒汉式(线程安全)

上一种在多线程环境下可能两个或者多个线程刚在 getInstance() 中的 if 判断环节通过后就切换线程,导致多次实例化

双重检验锁

与code1相比,需要加一个 private 锁变量,用于双重检验

// code2.
// .h
class Singleton{
private:
    static Singleton *unique;
    static std::mutex mutex_;	// #include <mutex>
    Singleton();
public:
    static Singleton *getInstance();
};
// .cpp
std::mutex Singleton::mutex_;
Singleton* Singleton::unique = nullptr;
Singleton::Singleton(){};
Singleton* Singleton::getInstance(){
    if(unique ==nullptr){
        mutex_.lock();
        if(unique ==nullptr){
            unique = new Singleton();
        }
        mutex_.unlock();
    }
    return unique;
}

饿汉式

线程安全:由于是加载时就声明了,不存在线程安全问题

内存安全:Singleton类里再定义一个类Gc,用Gc类的析构函数跟unique的内存回收进行绑定,然后Singleton类里弄一个静态Gc类小gc,这样小gc析构的时候,就可以在结束的时候完成垃圾回收。

//code3.
// .h
class Singleton{
public:
    static Singleton * getInstance();
    class Gc{
    public:
        ~Gc();
    };
private:
    static Singleton *unique;
    static Gc gc;
};


// .cpp
Singleton * Singleton::getInstance(){
    return unique;
}

Singleton::Gc::~Gc(){
    if (unique){
        delete unique;
    }
}

Singleton * Singleton::unique = new Singleton();
Singleton::Gc Singleton::gc;

参考

  1. 《大话设计模式》
  2. 《HeadFirst设计模式》
  3. c++单例模式

没看,以后万一学了java会看:
java单例模式

标签:Singleton,getInstance,Pattern,实例,Gc,单例,线程,unique
来源: https://www.cnblogs.com/codersyl/p/14747866.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有