懒汉式单例类

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

class Singleton
{
public:
    static Singleton* getInstance();

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() = default;

    static Singleton* instance;
    static mutex mtx;
};

Singleton *Singleton::instance = nullptr;
mutex Singleton::mtx;

Singleton* Singleton::getInstance()
{
    if (instance == nullptr)
    {
        lock_guard<mutex> lck(mtx);     // 注意这里 !!! 
        if (instance == nullptr)
        {
            instance = new Singleton();
        }
    }

    return instance;
}

void thread_func()
{
    Singleton* p = Singleton::getInstance();

    // p-> do something ...
}

int main()
{
    thread th1(thread_func);
    thread th2(thread_func);

    th1.join();
    th2.join();

    return 0;
}

饿汉式单例类

#include <iostream>
#include <thread>

using namespace std;

class Singleton
{
public:
    static Singleton* getInstance();

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() = default;
    static Singleton* instance;
};

Singleton *Singleton::instance = new Singleton();   // 注意这里 !!!
Singleton* Singleton::getInstance()
{
    return instance;
}

void thread_func()
{
    Singleton* p = Singleton::getInstance();

    // p-> do something ...
}

int main()
{
    thread th1(thread_func);
    thread th2(thread_func);

    th1.join();
    th2.join();

    return 0;
}

懒汉式的 call_once 实现

template <class Fn, class... Args>
  void call_once (once_flag& flag, Fn&& fn, Args&&... args);
  • 准确执行一次可调用对象 fn ,即使同时从多个线程调用。
#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

class Singleton
{
public:
    static Singleton* getInstance();

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() = default;

    static void createInstance();

    static Singleton* instance;
    static once_flag onceFlag;
};

void Singleton::createInstance()
{
    instance = new Singleton();
}

Singleton *Singleton::instance = nullptr;
once_flag Singleton::onceFlag;

Singleton* Singleton::getInstance()
{
    call_once(onceFlag, createInstance);  // 注意这里 !!!

    return instance;
}

void thread_func()
{
    Singleton* p = Singleton::getInstance();

    // p-> do something ...
}

int main()
{
    thread th1(thread_func);
    thread th2(thread_func);

    th1.join();
    th2.join();

    return 0;
}

单例类的资源清理【饿、懒同理】

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

class Singleton
{
    struct Recycle
    {
        ~Recycle()       // 注意这里 !!!
        {
            if (instance != nullptr)
            {
                delete instance;
                instance = nullptr;
            }
        }
    };

public:
    static Singleton* getInstance();

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() = default;
    ~Singleton();

    static Singleton* instance;
    static mutex mtx;
};

Singleton *Singleton::instance = nullptr;
mutex Singleton::mtx;

Singleton* Singleton::getInstance()
{
    if (instance == nullptr)
    {
        lock_guard<mutex> lck(mtx);
        if (instance == nullptr)
        {
            instance = new Singleton();
            static Recycle recycle;
        }
    }

    return instance;
}

Singleton::~Singleton()     // 注意这里 !!!
{
   // 单例类资源清理
}

void thread_func()
{
    Singleton* p = Singleton::getInstance();

    // p-> do something ...
}

int main()
{
    thread th1(thread_func);
    thread th2(thread_func);

    th1.join();
    th2.join();

    return 0;
}

TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧