设计模式——单例模式(慢加载)
来源:互联网 发布:linux文件系统书籍 编辑:程序博客网 时间:2024/06/05 22:46
这篇文章总结几种比较常用的设计模式,,,不懂得设计模式。。。怎么敢称熟悉OOP思想。
单例模式的核心结构中只包含一个被称为单例类的特殊类,通过单例模式可以保证系统中一个类只有一个实例
由于快加载单例模式是线程安全的,所以本文只讨论慢加载单例模式的线程安全问题
版本一 使用慢加载(懒加载),程序调用时再分配内存,然后初始化
class Singleton{public: static Singleton* getInstance() //该公有接口专门返回对象实例 { if(sobj == NULL) { sobj = new Signleton();//慢加载,程序调用时才生分配内存 } return sobj; }private: Singlenton(){}; //私有化构造函数 static Singlenton *sobj;}signlenton* signlenton::sobj = NULL;//慢加载,程序调用时才会生成,然后初始化
上述代码存在线程安全问题,if语句非原子操作,多线程调用时,会存在竞态条件
版本二 使用慢加载,考虑到多线程安全问题,使用互斥锁可以解决
1,考虑多线程调用时,是否存在竞态条件
2,考虑竞态条件,是否随着线程调度顺序的不同,而出现了不同的运行结果
3,发生竞态条件的代码段称为临界区代码段,临界区代码段都满足原子操作,为了保证原子操作,需要给临界区的代码段加上互斥锁进行控制,if语句不是原子操作,需要加互斥锁
class Singleton{public: static Singleton* getInstance() //该公有接口专门返回对象实例 { pthread_mutex_lock(&mutex);//加锁 if(sobj == NULL) { sobj = new Signleton();//慢加载,程序调用时才生分配内存 } pthread_mutex_unlock(&mutex);//解锁 return sobj; } ~Singlenton() { pthread_mutex_destroy(&mutex);//锁的销毁 }private: Singlenton(){}; //私有化构造函数 static Singlenton *sobj; static ptheread_mutex_t mutex;}signlenton* signlenton::sobj = NULL;//慢加载,程序调用时才会生成,然后初始化pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;//锁的初始化
上述互斥锁满足了 if语句的原子操作,实现了线程安全,但由于程序每调用一次,就会产生加锁解锁操作,对于单线程而言,降低了效率,所以代码还需要解决单线程的效率问题
版本三 由于存在单线程和多线程共存问题,提高单线程效率,需要使用双if语句
1,单线程存在效率低的问题,需要第二次调用的时候返回false
2,多线程仍需要注意竞态条件
class Singleton{public: static Singleton* getInstance() //该公有接口专门返回对象实例 { if(sobj == NULL) //双if语句,第二次调用不用进行加锁解锁操作 { pthread_mutex_lock(&mutex);//加锁 if(sobj == NULL) { sobj = new Signleton();//慢加载,程序调用时才生分配内存 } pthread_mutex_unlock(&mutex);//解锁 } return sobj; } ~Singlenton() { pthread_mutex_destroy(&mutex);//锁的销毁 }private: Singlenton(){}; //私有化构造函数 static Singlenton *sobj; static ptheread_mutex_t mutex;}signlenton* signlenton::sobj = NULL;//慢加载,程序调用时才会生成,然后初始化pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;//锁的初始化
上述代码提高了单线程效率,并实现线程是安全的,调用多线程时,当锁被释放后,线程缓存sobj的值刷新到原始内存中了,所以下次取值是在内存中取,是线程安全的。
阅读全文
0 0
- 设计模式——单例模式(慢加载)
- 设计模式—单例设计模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——组合模式
- STM32F10x_硬件I2C主从通信(轮询发送,中断接收)
- Mybatis学习笔记(十一)【一对一查询】
- 7-13 求链式线性表的倒数第K项(20 point(s))
- 求int型的最大取值(正数)
- 设计模式——单例模式(慢加载)
- ######保存角色,add表单页面Ajax传参给action,多个集合属性,【较为复杂的页面传参(封装ajax json参数)】:注意表单数据序列化,jquery遍历,json对象转String
- 《Python编程:从入门到实践 》[Eric Matthes著] 中文pdf非扫描版
- 思考2
- Mybatis学习笔记(十二)【一对多查询】
- Unity5权威讲解之菜鸟读书笔记(三)
- 201312-5 I'm stuck!
- linux下的关机命令和重启命令
- DeviceIoControl 直接从磁盘扇区读文件