zoukankan      html  css  js  c++  java
  • 设计模式复习-单例模式

    #pragma once
    #include "stdafx.h"
    #include<set>
    #include<string>
    #include<iostream>
    using 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<set>
    #include<string>
    #include<iostream>
    using 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();
             }
    
          }
      }
    }


    但是继续延伸一下,根据这里(

    https://blog.csdn.net/nodeathphoenix/article/details/51657973

    )的分析:双重锁也是不饿稳定的,那篇文章里引入了volatile来解决问题,感兴趣的可以了解一下,我的思路是用汇编处理这个地方。不管用什么方式,注意一点,就是编译器会对我们的代码进行优化。也就是变换了很多姿势,最后转出来的汇编是一样的。这个地方要注意。

     

  • 相关阅读:
    如何将本地项目发布到gitee?
    spingboot使用redis连接池报错
    swagger2中UI界面接口点击无法展开问题解决
    idea在Mybatis的xml里面写sql时,表名、字段、报红问题的解决方法
    svn如何创建分支
    Java 反射修改类的常量值、静态变量值、属性值
    Vue简单入门
    Ajax原理简说
    《机器学习Python实现_10_15_集成学习_lightgbm_进一步优化》
    《机器学习Python实现_10_14_集成学习_xgboost_优化介绍》
  • 原文地址:https://www.cnblogs.com/csnd/p/12061910.html
Copyright © 2011-2022 走看看