zoukankan      html  css  js  c++  java
  • 创建模式->单例模式

            对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管

    理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。   身份证号码  ,打印池     

          实现方法 ->让类自身负责保存它的唯一实例

        

           单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

          单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。单例模式又

    名单件模式或单态模式

    //单例模式  一个类只可以实例化一个对象 
    // 构造函数为私有的 但唯一的对象可以通过公有的GetInstance()获得
    // Singleton.h
    class Singleton
    {
    public:
    	static Singleton* GetInstance();
    private:
    	Singleton();
    	static Singleton* m_singleton;
    };
    // Singleton.cpp
    Singleton* Singleton::m_singleton = NULL;
    Singleton* Singleton::GetInstance()
    {
    	if(NULL == m_singleton)
    	{
    		m_singleton = new Singleton();
    	}
    	return Singleton;
    }
    单例模式

    单例模式优点:

    1. 提供了对唯一实例的受控访问 

    2. 由于在系统内存中只存在一个对象,因此可以节约系统资源

    3. 允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例

    单例模式缺点:

    1. 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难

    2. 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法(相比与 工厂模式相比)

    3. 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言(JavaC#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。


    单例模式适用情况包括:系统只需要一个实例对象;客户调用类的单个实例只允许使用一个公共访问点。

    当涉及到多线程同时访问GetInstance() 函数时   需要加入lock 确保一个线程位于代码的临界区 这样另外一个线程就不进入临界区。其他线程要等待 进入

            

    Singleton* Singleton::GetInstance()
    {
    	lock(syncRoot)
    	{
    		if(NULL == m_singleton)
    		{
    			m_singleton = new Singleton();
    		}
    	}
    	return Singleton;
    }
     

    这样的不好之处在于每次调用GetInstance() 都要调用lock 我们可以加入双重锁定 Double-Check-Locking

    Singleton* Singleton::GetInstance()
    {
    	if(NULL == m_singleton)
    	{
    		lock(syncRoot)
    		{
    			if(NULL == m_singleton)
    			{
    				m_singleton = new Singleton();
    			}
    		}
    	}
    	return Singleton;
    }

          当有两个NULL 的m_singleton时 第一个NULL==m_singleton都可以进入, 但是由于lock机制 只有一个可以进入第二个NULL if语句里, 这样第一个进入的new 了 第二个进入的无法再执行new了。 

          我们最先了解的就是懒汉式 例类   要在第一次引用时 才会将自己实例化  但这面临着 多线程问题 需要双重锁定解决 访问安全问题。

         饿汉式 例类 在自己被加载时就将自己实例化了,提前占用了系统资源。保证安全问题。


     饿汉式单例类在自己被加载时就将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。


    懒汉式单例类在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有

    可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,需要通过同步化机制进行控制。

    工厂模式

    关注公众号 海量干货等你
  • 相关阅读:
    分布式事务基本概念
    rocketmq源码分析3-consumer消息获取
    Mac下的Eclipse不能记住工作空间问题
    rocketmq源码分析2-broker的消息接收
    rocketmq源码分析1-benchmark学习
    metrics
    slf4j与logback对接是如何将日志写到控制台的
    Spring AOP
    hibernate数据库连接池,常用配置
    动态代理
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734433.html
Copyright © 2011-2022 走看看