标签:std tmp Singleton nullptr instance 课程 单例 new 设计模式
- 属于“对象性能”模式
- 面向对象很好地解决了“抽象”的问题,但不可避免地要付出一定的代价。对于通常情况来讲,面向对象的成本大都可忽略不计(继承),但某些特殊情况,面向对象带来的成本须谨慎处理(虚函数倍乘效应)
- 动机:软件系统中有些特殊的类,必须确保它们在系统中只存在一个实例,才能确保逻辑正确及良好的效率
- 确保一个类仅有一个实例,并提供一个该实例的全局访问点
- 如何绕过常规构造器,提供一种机制,保证类只有一个实例
- 类设计者的责任,而不是使用者的责任
- 拷贝构造函数设计成私有(c++中,缺省构造函数和缺省拷贝构造函数都是共有的)
- 高并发场景下,锁的代价过大
- 双检查锁(锁前锁后都检查,防止两个进程前后脚进来),但内存读写reorder不安全,会导致双检查锁失效(线程在指令层次抢时间片,可能与代码顺序不一致)
- new的默认顺序:分配内存--调用构造器--地址赋值给变量;实际优化后的可能顺序:分配内存--地址赋值给变量--调用构造器(导致线程B拿到了内存地址,而并没有执行构造器)
- 解决:new过程不能reoder。Java:加volatile声明;C++atomic,memory_order_relaxed/release
- Singleton模式中的实例构造器可设置为protected以允许子类派生
- Singleton一般不支持拷贝构造函数和Clone接口,因为有可能导致多个对象实例,与模式初衷违背
- 双锁检查正确实现,确保多线程环境下安全的Singleton
1 class Singleton{ 2 private: 3 Singleton(); 4 Singleton(const Singleton& other); 5 public: 6 static Singleton* getInstance(); 7 static Singleton* m_instance; 8 }; 9 10 Singleton* Singleton::m_instance=nullptr; 11 12 //线程非安全版本 13 Singleton* Singleton::getInstance() { 14 if (m_instance == nullptr) { 15 m_instance = new Singleton(); 16 } 17 return m_instance; 18 } 19 20 //线程安全版本,但锁的代价过高 21 Singleton* Singleton::getInstance() { 22 Lock lock; 23 if (m_instance == nullptr) { 24 m_instance = new Singleton(); 25 } 26 return m_instance; 27 } 28 29 //双检查锁,但由于内存读写reorder不安全 30 Singleton* Singleton::getInstance() { 31 32 if(m_instance==nullptr){ 33 Lock lock; 34 if (m_instance == nullptr) { 35 m_instance = new Singleton(); 36 } 37 } 38 return m_instance; 39 } 40 41 //C++ 11版本之后的跨平台实现 (volatile) 42 std::atomic<Singleton*> Singleton::m_instance; 43 std::mutex Singleton::m_mutex; 44 45 Singleton* Singleton::getInstance() { 46 Singleton* tmp = m_instance.load(std::memory_order_relaxed); 47 std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence 48 if (tmp == nullptr) { 49 std::lock_guard<std::mutex> lock(m_mutex); 50 tmp = m_instance.load(std::memory_order_relaxed); 51 if (tmp == nullptr) { 52 tmp = new Singleton; 53 std::atomic_thread_fence(std::memory_order_release);//释放内存fence 54 m_instance.store(tmp, std::memory_order_relaxed); 55 } 56 } 57 return tmp; 58 }View Code
标签:std,tmp,Singleton,nullptr,instance,课程,单例,new,设计模式 来源: https://www.cnblogs.com/cxc1357/p/12310649.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。