单件模式(Sginleton Pattern)

单件模式:用来创建独一无二的,只能有一个实例的对象。将使用和构造分离。

线程池(threadpool)、缓存(cache)、对话框、处理器、注册表对象、日志对象、打印机驱动程序对象、显卡设备驱动程序对象。
单件模式确保一个类之哟一个实例,并提供一个全局访问点。

这里写图片描述
意图: 希望对象只有一个实例,单没有控制对象实例化的全局对象。还希望确保所有实体使用该对象相同的实例,无需将引用传给它们。
问题来了(多线程):
Double-Checked Locking 双重加锁模式

这里写图片描述
在C++中,可能会导致内存泄漏—-创建了两个对象,销毁时,只销毁了其中一个。

线程同步:

public class Singleton{
    // 静态初始化器(static initializer)中创建单件,保证了线程安全。
    private static Singleton uniqueInstance;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if(uniqueInstance == null)
            uniqueInstance = new Singleton();
        return uniqueInstance;
    }
}

但是每次执行都要先同步,判断对象是否存在,这样会严重影响性能。

public class Singleton{
    private volatile static Singleton uniqueInstance;
    private Singleton(){}
    private static Singleton getInstance(){
        if(uniqueInstance = null){
            //synchronized (Singleton.class){
            synchronized (this){
                if (uniqueInstance = null)
                    uniqueInstance = new Singleton();
            }
        }
    }
}

当两个线程都运行到if(uniqueInstance = null)时候,都会执行下一句。等待同步。此句最多执行一次。(《Effective C++》、《More Effective C++》)
C++ Singleton design pattern

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                                  // Instantiated on first use.
            return instance;
        }
    private:
        S() {};                   // Constructor? (the {} brackets) are needed here.

        // C++ 03
        // ========
        // Dont forget to declare these two. You want to make sure they
        // are unacceptable otherwise you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement

        // C++ 11
        // =======
        // We can use the better technique of deleting the methods
        // we don't want.
    public:
        S(S const&)               = delete;
        void operator=(S const&)  = delete;

        // Note: Scott Meyers mentions in his Effective Modern
        //       C++ book, that deleted functions should generally
        //       be public as it results in better error messages
        //       due to the compilers behavior to check accessibility
        //       before deleted status
};

单例模式(C++):

class StringSingleton
{
public:
    // Some accessor functions for the class, itself
    std::string GetString() const {return mString; }
    void SetString( const std::string & newString) { mString = newStr ; }

     // The magic function, which allows access to the class from anywhere
     // To get the value of the instance of the class, call:
     //     StringSingleton::Instance().GetString();
      static StringSingleton &Instance()
     {
         // This line only runs once, thus creating the only instance in existence
         static StringSingleton *instance = new StringSingleton;
         // dereferencing the variable here, saves the caller from having to use 
         // the arrow operator, and removes temptation to try and delete the 
         // returned instance.
         return *instance; // always returns the same instance
     }

 private: 
     // We need to make some given functions private to finish the definition of the singleton
     StringSingleton(){} // default constructor available only to members or friends of this class

     // Note that the next two functions are not given bodies, thus any attempt 
     // to call them implicitly will return as compiler errors. This prevents 
     // accidental copying of the only instance of the class.
     StringSingleton(const StringSingleton &old); // disallow copy constructor
     const StringSingleton &operator=(const StringSingleton &old); //disallow assignment operator

     // Note that although this should be allowed, 
     // some compilers may not implement private destructors
     // This prevents others from deleting our one single instance, which was otherwise created on the heap
     ~StringSingleton(){} 
 private: // private data for an instance of this class
     std::string mString;
}

互斥锁(C++)

#include <iostream>
using namespace std;

/* Place holder for thread synchronization mutex */
class Mutex
{   /* placeholder for code to create, use, and free a mutex */
};

/* Place holder for thread synchronization lock */
class Lock
{   public:
        Lock(Mutex& m) : mutex(m) { /* placeholder code to acquire the mutex */ }
        ~Lock() { /* placeholder code to release the mutex */ }
    private:
        Mutex & mutex;
};

class Singleton
{   public:
        static Singleton* GetInstance();
        int a;
        ~Singleton() { cout << "In Destructor" << endl; }

    private:
        Singleton(int _a) : a(_a) { cout << "In Constructor" << endl; }


        static Mutex mutex;

        // Not defined, to prevent copying
        Singleton(const Singleton& );
        Singleton& operator =(const Singleton& other);
};

Mutex Singleton::mutex;

Singleton* Singleton::GetInstance()
{
    Lock lock(mutex);

    cout << "Get Instance" << endl;

    // Initialized during first access
    static Singleton inst(1);

    return &inst;
}

int main()
{
    Singleton* singleton = Singleton::GetInstance();
    cout << "The value of the singleton: " << singleton->a << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值