b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

单一模式

电脑杂谈  发布时间:2020-04-07 02:05:11  来源:网络整理

单例模式举例_singleton单例模式_单例模式 c++

1. 概念

所谓的单例模式是为了确保一个类只有一个实例singleton单例模式,并提供一个全局访问点.

2. UML图

3. 应用场景

举个小例子,在Windows桌面上,我们打开了一个回收站. 当我们尝试再次打开新的回收站时,Windows系统将不会为您弹出新的回收站窗口. 也就是说,在整个系统运行期间,系统仅维护一个回收站实例. 这是典型的单例模型.

因此,单例模式的应用场景为:

单例模式 c++_单例模式举例_singleton单例模式

①需要经常创建和销毁的对象;

②需要花费大量时间或资源来创建但经常使用的对象;

③工具对象;

④经常访问或文件的对象.

4. 实施思路

从单例模式的概念开始(确保一个类只有一个实例,并提供一个访问它的全局访问点),该概念可以分为两部分: (1)确保只有一个实例类的实例; 2)提供一个全局访问点进行访问.

问: 如何确保一个类只有一个实例?

单例模式 c++_单例模式举例_singleton单例模式

答案: 定义私有构造函数无法通过外界的new创建实例(通常,当我们创建新类时,如果不编写构造函数,则编译器默认会生成一个公共的无参数构造函数. 您可以使用new来创建该类的实例).

问: 那您要在哪里创建类的实例?

答案: 在类别中创建. 要创建类的实例,您需要一个私有变量来保存该实例,并且为了确保在多线程情况下只有一个实例,它必须是静态变量.

问: 外界如何获得此类的实例以使用它?

答案: 定义一个公共方法以提供一个全局访问点,并定义公共属性以提供一个全局访问点.

5. 实施代码

    // 单例模式的实现
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;
        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }
        // 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        public static Singleton GetInstance()
        {
            // 如果类的实例不存在则创建,否则直接返回
            if (uniqueInstance == null)
            {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
    }

单例模式举例_单例模式 c++_singleton单例模式

上面的单例模式实现确实在单线程下是完美的,但是,在多线程的情况下,您将获得多个单例实例,因为当两个线程同时运行GetInstance方法时,两个线程将判断(uniqueInstance == null)此条件返回true. 这时,两个线程都将创建一个Singleton实例,这违反了我们对Singleton模式的初衷. 由于上述实现将运行多个线程来执行,因此我们的多线程解决方案自然是使GetInstance方法一次仅运行一个线程,即需要线程同步.

    //单例模式的实现
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton uniqueInstance;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }
        //定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        public static Singleton GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }

问题: 为什么需要在多线程GetInstance中进行两个(uniqueInstance == null)判断?最好只判断一个?

说明: 当uniqueInstance不为null时,您仅需要直接返回uniqueInstance对象,而无需锁定辅助对象. 锁定会增加额外的开销,并且会降低性能singleton单例模式,因此我们只需要在判断可以避免锁定的额外开销之前添加一个语句(uniqueInstance == null)即可. 此实现称为“双重锁定”,这是第一种(uniqueInstance == null)的必要性. 在多线程中,如果两个线程同时运行锁的外层的if(uniqueInstance == null),则会同时建立两个线程. 第一个线程锁定并实例化一个对象. 解锁后,如果没有判断,第二个线程将直接实例化一个对象,这不是单例. 因此,第二个(uniqueInstance == null)判断也是必要的.

6. 主要优点

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

②由于系统内存中仅存在一个对象,因此可以节省系统资源,某些需要频繁创建和销毁的对象的单例模式无疑可以提高系统性能.

singleton单例模式_单例模式举例_单例模式 c++

③允许可变数量的实例.

7. 主要缺点

①由于简单兴趣模型中没有抽象层,因此很难扩展单例类.

②单例类别的职责过于沉重,在一定程度上违反了“单一职责原则”.

③单例滥用会带来一些负面问题. 例如,为了节省资源,连接池对象被设计为一个单例类,这可能导致共享该连接池对象的程序过多,连接池将溢出. 该对象长时间不使用,系统将被视为垃圾并被回收,这将导致对象状态的丢失.

返回(23种设计模式)

参考:

1,C#设计模式(1)-单例模式

2. 单例模式的使用和应用场景

3. 单例模式的八种书写方式


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-166525-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 黄兴
        黄兴

        知道为什么中共对所谓的岛内运动不屑一顾吗

      • 张岭
        张岭

        10月16日一定去看

      热点图片
      拼命载入中...