• 设计模式-单例模式(Singleton)


    单例模式(Singleton)可以说是最简单也是最常见的设计模式了;

    单例模式保证一个类仅有一个实例;单例模式根据初始化形式分为懒汉模式饿汉模式

    下面4种方式为单利模式的实现代码,推荐使用后两种。 

    第一种:最简单的最不推荐的方式:

    缺点:该方式在多线程的程序中可能会创建多个实例

      public class Singleton
      {
            private static Singleton instance;  
            /// <summary>
            /// 默认构造函数必须设置为private;禁止在类外创建对象实例
            /// </summary>
            private Singleton() { }
    
            /// <summary>
            /// 单线程下的单利模式
            /// 缺点:在多线程中,可能会存在多个实例
            /// </summary>
            /// <returns></returns>
            public static Singleton GetInstance()
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            } 
        }

    第二种:在创建对象时加锁,保证可以在多线程程序中使用

    缺点:每次访问必须加锁,所以执行效率相当较低所以也不推荐

    public class ThreadSingleton
        {
            private static ThreadSingleton instance;
            private static readonly object obj = new object();
            private ThreadSingleton() { } 
    
            /// <summary>
            /// 多线程下的单利模式;
            /// 缺点:每次访问都要进行lock,降低程序执行效率
            /// </summary>
            /// <returns></returns>
            public static ThreadSingleton GetInstance()
            {
                lock (obj)
                {
                    if (instance == null)
                    {
                        instance = new ThreadSingleton();
                    }
                }
                return instance;
            } 
        }

    第三种:可以在多线程中程序中应用,该方式不用线程每次都加锁,只有在实例未创建的时候才加锁处理。同时保证了多线程的安全,所以该方式称为双重锁定。

    public class DoubleCheckLockingSingleton
        {
            private static DoubleCheckLockingSingleton instance;
            private static readonly object obj = new object(); 
            private DoubleCheckLockingSingleton() { }
    
            /// <summary>
            /// 双重锁定
            /// 不用线程每次都加锁,只有在实例未创建的时候需要加锁,提高程序执行效率
            /// </summary>
            /// <returns></returns>
            public static DoubleCheckLockingSingleton GetInstance()
            {
                if (instance == null)
                {
                    lock (obj)
                    {
                        if (instance == null)
                        {
                            instance = new DoubleCheckLockingSingleton();
                        }
                    }
                }
                return instance;
            } 
     }

    第四种:C#本身提供了一种“静态初始化”的方法,这种方法不需要开发人员显式的编写线程安全代码,便可以解决多线程中的不安全问题。和第三种方式相比这种方式编写的代码最简洁,所以也是最推荐的一种方式。

    “静态初始化”方式在程序加载时就实现了实例化,所以被形象的称为饿汉单例模式;上面三种方式在第一次被引用的时候才实例化,所以称为懒汉单例模式

        /// <summary>
        /// 添加sealed关键字,阻止派生类;派生类可能会增加实例
        /// </summary>
        public sealed class SealedSingleton
        {
            /// <summary>
            /// 在第一次引用该类时进行初始化;
            /// 这种静态初始化的方式在加载时就初始化对象,所以被形象的成为饿汉模式
            /// </summary>
            private static readonly SealedSingleton instance = new SealedSingleton();
            private SealedSingleton() { }
    
            public static SealedSingleton GetInstance()
            {
                return instance;
            }
        }

     

  • 相关阅读:
    linux 文件系统(inode和block)
    vue状态管理vuex从浅入深详细讲解
    小白都能看懂的vue中各种通信传值方式,附带详细代码
    CSS3移动端vw+rem不依赖JS实现响应式布局
    JavaScript原生封装ajax请求和Jquery中的ajax请求
    永久解决Sublime包管理package control 打开install package报错 There are no packages available for installation
    从GitLab上创建分支本地拉取项目和提交项目详解
    前端路由的两种实现方式,内附详细代码
    几个例子理解浅拷贝和深拷贝
    讲解JavaScript中对闭包的理解
  • 原文地址:https://www.cnblogs.com/zhaochengshen/p/10065414.html
Copyright © 2020-2023  润新知