C++ 线程安全的单例模式
来源:互联网 发布:苹果手机用4g网络很卡 编辑:程序博客网 时间:2024/06/03 21:39
废话不多说,常用的代码积淀下来。
一、懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。
需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread safety.
使用double-check来保证thread safety.但是如果处理大量数据时,该锁才成为严重的性能瓶颈。
1、静态成员实例的懒汉模式:
1 class Singleton 2 { 3 private: 4 static Singleton* m_instance; 5 Singleton(){} 6 public: 7 static Singleton* getInstance(); 8 }; 9 10 Singleton* Singleton::getInstance()11 {12 if(NULL == m_instance)13 {14 Lock();//借用其它类来实现,如boost15 if(NULL == m_instance)16 {17 m_instance = new Singleton;18 }19 UnLock();20 }21 return m_instance;22 }
2、内部静态实例的懒汉模式
这里需要注意的是,C++0X以后,要求编译器保证内部静态变量的线程安全性,可以不加锁。但C++ 0X以前,仍需要加锁。
1 class SingletonInside 2 { 3 private: 4 SingletonInside(){} 5 public: 6 static SingletonInside* getInstance() 7 { 8 Lock(); // not needed after C++0x 9 static SingletonInside instance;10 UnLock(); // not needed after C++0x11 return instance; 12 }13 };
二、饿汉模式:即无论是否调用该类的实例,在程序开始时就会产生一个该类的实例,并在以后仅返回此实例。
由静态初始化实例保证其线程安全性,WHY?因为静态实例初始化在程序开始时进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。
故在性能需求较高时,应使用这种模式,避免频繁的锁争夺。
1 class SingletonStatic 2 { 3 private: 4 static const SingletonStatic* m_instance; 5 SingletonStatic(){} 6 public: 7 static const SingletonStatic* getInstance() 8 { 9 return m_instance;10 }11 };12 13 //外部初始化 before invoke main14 const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic;
(完)
评论列表
不错
支持(0)反对(0)
谢谢楼主的分享;看了楼主的文章,让小弟地壶灌顶啊。才知道自己的渺小。
对于楼主的这篇文章,由于小弟学艺不精,有几个地方看不懂~希望能得到楼主的指教。提前谢过了。
在“二、饿汉模式”中,SingletonStatic类的构造函数已经是private的了,怎么还可以在外部进行new实例化操作,楼主的代码,小弟已经运行过了,确实没有错误,但是小弟着实不懂,希望得到你的解答。谢谢。
对于楼主的这篇文章,由于小弟学艺不精,有几个地方看不懂~希望能得到楼主的指教。提前谢过了。
在“二、饿汉模式”中,SingletonStatic类的构造函数已经是private的了,怎么还可以在外部进行new实例化操作,楼主的代码,小弟已经运行过了,确实没有错误,但是小弟着实不懂,希望得到你的解答。谢谢。
支持(0)反对(0)
@ 宁采臣
路过,楼主的文章的确不错,对于你的问题,可以这样解答:private是类外不能访问的,但你看上述,它是通过类内元素m_instance进行new操作的,所以能够成功。
对于为何这里要采用const static,表示不是很理解
路过,楼主的文章的确不错,对于你的问题,可以这样解答:private是类外不能访问的,但你看上述,它是通过类内元素m_instance进行new操作的,所以能够成功。
对于为何这里要采用const static,表示不是很理解
支持(0)反对(0)
@ 宁采臣
因为这个new实例化不是new对象,而是初始化(initialization),C++标准规定,非整型和枚举型静态常量类成员需要在类外进行初始化,就是说假如你写成:
private:
static const SingletonStatic* m_instance = new SingletonStatic;
编译是不成功的,因为这类声明只是个“声明式”(declaration)
,而不是“定义式”(definition),你尝试在类声明中进行初始化的话,编译不知道把这个对象初始化到哪去。
但是假如你的静态常量类成员是整型或枚举型的,却可以这样做,如:
private:
static const int someInt = 2;
为什么整型或枚举型可以,这是编译器层面的东西了,可以简单理解为因为这个静态常量类成员是一个整数,可以直接表示为机器数(当然是常量)。
这么说希望你能明白。
因为这个new实例化不是new对象,而是初始化(initialization),C++标准规定,非整型和枚举型静态常量类成员需要在类外进行初始化,就是说假如你写成:
private:
static const SingletonStatic* m_instance = new SingletonStatic;
编译是不成功的,因为这类声明只是个“声明式”(declaration)
,而不是“定义式”(definition),你尝试在类声明中进行初始化的话,编译不知道把这个对象初始化到哪去。
但是假如你的静态常量类成员是整型或枚举型的,却可以这样做,如:
private:
static const int someInt = 2;
为什么整型或枚举型可以,这是编译器层面的东西了,可以简单理解为因为这个静态常量类成员是一个整数,可以直接表示为机器数(当然是常量)。
这么说希望你能明白。
支持(1)反对(0)
@ Moondark
const和static都是必须的
const是保证这个单例对象不会被修改,
static是保证这个单例对象在程序开始时进入主函数之前就被初始化了,而且是线程安全的。
都是出于安全性的需求
const和static都是必须的
const是保证这个单例对象不会被修改,
static是保证这个单例对象在程序开始时进入主函数之前就被初始化了,而且是线程安全的。
都是出于安全性的需求
支持(0)反对(0)
const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic;
作为初始化的理解很受用,好文章。
作为初始化的理解很受用,好文章。
支持(0)反对(0)
3 private:
4 static const SingletonStatic* m_instance;
5 SingletonStatic(){}
6 public:
7 static SingletonStatic* getInstance()
8 {
9 return m_instance;
10 }
将一个常量变成变量返回,你不觉得会编译不过吗?
4 static const SingletonStatic* m_instance;
5 SingletonStatic(){}
6 public:
7 static SingletonStatic* getInstance()
8 {
9 return m_instance;
10 }
将一个常量变成变量返回,你不觉得会编译不过吗?
0 0
- 设计模式 - 线程安全的单例模式(C#)
- object-c 单例模式的线程安全
- 线程安全单例模式(C++)
- 线程安全单例模式(C++)
- 线程安全的单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- Volatile 线程安全的单例模式
- 线程安全的单例模式
- 基于线程安全的单例模式
- 线程安全的单例模式
- 单例模式的线程安全
- 线程安全的单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- PayPal集成标准版案例(asp.net)关键源码
- Spring整合JMS(三)——MessageConverter介绍
- SQL Profile 总结(四)--使用示例
- Tomcat服务器证书的配置(SSL)
- Linux常用环境变量(基础内容)
- C++ 线程安全的单例模式
- android dialog在activity中,如何处理activity捕捉不到back点击事件
- 完美解决VS2003.Net fatal error LNK1201: 写入程序数据库“.pdb”时出错
- 漫谈Android 增量更新
- Android使用Downloadmanager进行下载时,鉴别取消下载和下载完成的广播
- Microsoft CryptoAPI加密技术
- 算法理解的整理
- LeetCode 260. Single Number III
- C语言实现 select模式编程