设计模式复习-单例模式
#pragma once#include "stdafx.h"#include#include#includeusing namespace std;/*设计模式-单例模式(Singleton) 保证一个类仅有一个实例,并提供一个访问它的全局访问节点。[懒汉模式涉及多线程上锁问题,饿汉模式不涉及多线程上锁问题] 下面实现懒汉跟饿汉模式,先不考虑上锁问题,最后补充。*//*设计模式-迭代器模式(Iterator)提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露该对象内部表示。(现在好多语言都已经内置实现了这个功能了,所以实际用途不大,但是建议写一下,实现过程价值远远大于使用价值。)*///懒汉模式class Cwork {private: static Cwork *m_cWork; static int m_nMarkRunCount; Cwork() {}//注意,构造函数私有化可以限制其他人去实例化这个类。 void DoWrite() { cout << "WorkCiunt:" << m_nMarkRunCount++ << endl; }public: static void GetInstance() { if (m_cWork == NULL) { m_cWork = new Cwork(); } } static void WrkteLog() { if (m_cWork == NULL) { cout << "no instance" << endl; return; } m_cWork->DoWrite(); }};Cwork * Cwork::m_cWork = NULL;int Cwork::m_nMarkRunCount = 0;int main() { Cwork::WrkteLog(); Cwork::GetInstance(); Cwork::WrkteLog(); getchar(); return 0;}
#pragma once#include "stdafx.h"#include#include#includeusing namespace std;//饿汉模式class Cwork {private: static Cwork *m_cWork; static int m_nMarkRunCount; Cwork() {}//注意,构造函数私有化可以限制其他人去实例化这个类。 void DoWrite() { cout << "WorkCiunt:" << m_nMarkRunCount++ << endl; }public: static Cwork* GetInstance() { if (m_cWork == NULL) { m_cWork = new Cwork(); } return m_cWork; } static void WrkteLog() { if (m_cWork == NULL) { cout << "no instance" << endl; return; } m_cWork->DoWrite(); }};Cwork * Cwork::m_cWork = Cwork::GetInstance();int Cwork::m_nMarkRunCount = 0;int main() { Cwork::WrkteLog(); Cwork::WrkteLog(); getchar(); return 0;}
还有就是锁的问题。多线程环境下使用单例模式中的懒汉模式会涉及到上锁问题,主要是在这个地方:
上面是一个传统的上锁模式,但是这个会有一个资源浪费问题,就是虽然m_cWork已经不等于NULL了,但是还是会不停的上锁和解锁,上锁和解锁涉及到内核态和用户态的转换,这回导致资源浪费。于是便引出了双重锁的概念,双重锁全称双重检查锁定模式,缩写DCLP。
大体姿势是这样:
Static void GetInstance(){ If(m_cWork == NULL){ Lock{ If(m_cWork == NULL){ m_cWork = new CWork(); } } }}
但是继续延伸一下,根据这里的分析:双重锁也是不饿稳定的,那篇文章里引入了volatile来解决问题,感兴趣的可以了解一下,我的思路是用汇编处理这个地方。不管用什么方式,注意一点,就是编译器会对我们的代码进行优化。也就是变换了很多姿势,最后转出来的汇编是一样的。这个地方要注意。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~