Skip to content

Latest commit

 

History

History
153 lines (114 loc) · 3.15 KB

29、分别写出饿汉和懒汉线程安全的单例模式.md

File metadata and controls

153 lines (114 loc) · 3.15 KB

29、分别写出饿汉和懒汉线程安全的单例模式

​ 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。根据单例对象创建时间,可分为两种模式:懒汉模式和饿汉模式。

​ 懒汉模式:延迟加载,不到万不得已不会去实例化类,也就是说第一次用到类实例的时候才会实例化。

#include <iostream>
#include <mutex>
 
using namespace::std;
 
// 懒汉模式一:多线程不安全
template <typename T>
class Singleton
{
public:
    static T* getInstance()
    {
        if (instance_ == nullptr)
        {
            instance_ = new T();
        }
 
        return instance_;
    }
 
private:
    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
 
private:
    static T* instance_;
};
 
template <typename T>
T* Singleton<T>::instance_ = nullptr;
 
// 懒汉模式二:多线程安全
template <typename T>
class Singleton2
{
public:
    static T* getInstance()
    {
        if (instance_ == nullptr)
        {
            mutex_.lock();
 
            if (instance_ == nullptr)
            {
               instance_ = new T();
            }
 
            mutex_.unlock();
        }
 
        return instance_;
    }
 
private:
    Singleton2() = delete;
    Singleton2(const Singleton2&) = delete;
    Singleton2& operator=(const Singleton2&) = delete;
 
private:
    static T* instance_;
    static mutex mutex_;
};
 
template <typename T>
T* Singleton2<T>::instance_ = nullptr;
 
template <typename T>
mutex Singleton2<T>::mutex_;
 
 
class Printer
{
    friend class Singleton<Printer>;
    friend class Singleton2<Printer>;
 
private:
    Printer() = default;
    Printer(const Printer&) = delete;
    Printer& operator=(const Printer&) = delete;
 
public:
    void print() { cout << "Printer" << endl; }
};
 
 
int main(int argc, char* argv[])
{
    Singleton<Printer>::getInstance()->print();
    Singleton2<Printer>::getInstance()->print();
}
 

饿汉模式:在单例类定义的时候(即在main函数之前)就进行实例化。因为main函数执行之前,全局作用域的类成员变量instance_已经初始化,故没有多线程的问题。

#include <iostream>
#include <mutex>
 
using namespace::std;
 
// 饿汉模式
template <typename T>
class Singleton
{
private:
    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
 
public:
    static T* getInstance()
    {
        return instance_;
    }
 
private:
    static T* instance_;
};
 
template <typename T>
T* Singleton<T>::instance_ = new T();
 
class Printer
{
    friend class Singleton<Printer>;
 
private:
    Printer() = default;
    Printer(const Printer&) = delete;
    Printer& operator=(const Printer&) = delete;
 
public:
    void print() { cout << "Printer" << endl; }
};
 
 
int main(int argc, char* argv[])
{
    Singleton<Printer>::getInstance()->print();
}