【Design Pattern】C++ 线程安全的单例模式
2016-03-22 22:08
555 查看
顾名思义,单例模式是用来保证这个类在运行期间只会被创建一个类实例,另外,单例模式还提供了一个全局唯一访问这个类实例的访问点,就是getInstance方法1。
下面看看该类的实现
首先看看标准教科书式的单例模式
头文件:
cpp:
然而这个单例模式就线程安全了吗?答案是否定的。当m_instance == NULL(对象还未被实例化的时候),此时A线程调用Singleton::getInstance(),当A线程跑完if()判断条件后,正要进行m_instance = new Singleton;的时候,CPU时间片耗完了,于是B线程此时又来调用getInstance()方法,当B线程实例化完成了Singleton之后,时间片又回到了A线程,此时A线程又会实例化一个Singleton,这就会造成内存泄露。
那么,线程安全的单例模式怎么写?需要用到线程同步吗?用到线程同步当然可以!但是还有更好的方法。
.h:
.cpp:
因为静态的变量在程序开始时最先被初始化,因此这样的单例模式不存在线程安全的问题,也省去了每次调用getInstance()的时候都要判断m_instance是否为空。
陈臣 (2011-01-01). 研磨设计模式 (Kindle Locations 1677-1679). 清华大学出版社. Kindle Edition. ↩
下面看看该类的实现
首先看看标准教科书式的单例模式
头文件:
// // Singleton.h // DesignPattern // // Created by NULL on 3/22/16. // Copyright © 2016 NCL. All rights reserved. // #ifndef Singleton_h #define Singleton_h #include <stdio.h> class Singleton { private: static Singleton * m_instance; Singleton(); ~Singleton(); public: static Singleton * getInstance(); }; #endif /* Singleton_hpp */
cpp:
// // Singleton.cpp // DesignPattern // // Created by NULL on 3/22/16. // Copyright © 2016 NCL. All rights reserved. // #include "Singleton.h" Singleton* Singleton::getInstance() { if ( NULL == m_instance ) { m_instance = new Singleton; } return m_instance; } Singleton* Singleton::m_instance = NULL;
然而这个单例模式就线程安全了吗?答案是否定的。当m_instance == NULL(对象还未被实例化的时候),此时A线程调用Singleton::getInstance(),当A线程跑完if()判断条件后,正要进行m_instance = new Singleton;的时候,CPU时间片耗完了,于是B线程此时又来调用getInstance()方法,当B线程实例化完成了Singleton之后,时间片又回到了A线程,此时A线程又会实例化一个Singleton,这就会造成内存泄露。
那么,线程安全的单例模式怎么写?需要用到线程同步吗?用到线程同步当然可以!但是还有更好的方法。
.h:
// // Singleton_Thread_Safe.h // DesignPattern // // Created by NULL on 3/22/16. // Copyright © 2016 NCL. All rights reserved. // #ifndef Singleton_Thread_Safe_h #define Singleton_Thread_Safe_h #include <stdio.h> class Singleton_Thread_Safe { private: static Singleton_Thread_Safe * m_instance; Singleton_Thread_Safe(); ~Singleton_Thread_Safe(); public: static Singleton_Thread_Safe * getInstance(); }; #endif /* Singleton_Thread_Safe_hpp */
.cpp:
// // Singleton_Thread_Safe.cpp // DesignPattern // // Created by NULL on 3/22/16. // Copyright © 2016 NCL. All rights reserved. // #include "Singleton_Thread_Safe.h" Singleton_Thread_Safe* Singleton_Thread_Safe::getInstance() { return m_instance; } Singleton_Thread_Safe* Singleton_Thread_Safe::m_instance = new Singleton_Thread_Safe;
因为静态的变量在程序开始时最先被初始化,因此这样的单例模式不存在线程安全的问题,也省去了每次调用getInstance()的时候都要判断m_instance是否为空。
陈臣 (2011-01-01). 研磨设计模式 (Kindle Locations 1677-1679). 清华大学出版社. Kindle Edition. ↩
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性