• 单例模式 Singelton


    1.什么是单例模式

      保证一个类最多只有一个实例(实例化控制),并且提供一个访问它的全局访问点(全局访问)。

    2.什么时候用

      当创建一个对象比较耗费资源,而这个对象的实例只要有一个就可以使用,这个时候可以用到单例模式。

      单例模式解决了,如何实现一个类只能被创建一次的问题。

    3.代码示例

    using System;
    
    namespace mydotnet
    {
        class Program
        {
            static void Main(string[] args)
            {
                Singleton singleton =  Singleton.GetInstance();//客户端获取实例
            }
        }  
    
        public sealed class Singleton
        {
            private Singleton(){}//私有化构造函数,防止外部实例化内部可以使用
    
            private static Singleton instance;//必须是静态的,静态方法才能调用
    
            public static Singleton GetInstance(){//公用静态方法,外部可以调用
                if(instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }      
    
        }
    }

    4.并发问题解决

    上述代码是懒汉模式,第一次使用才会创建。发生并发时,可能会多次创建,解决并发可以考虑加lock。代码如下:

    using System;
    
    namespace mydotnet
    {
        class Program
        {
            static void Main(string[] args)
            {
                Singleton singleton =  Singleton.GetInstance();//客户端获取实例
            }
        }  
    
        public sealed class Singleton
        {
            private Singleton(){}//私有化构造函数,防止外部实例化,内部可以使用
    
            private static Singleton instance;//必须是静态的,静态方法才能调用
    
            private static readonly object syncLock = new object();//不直接锁定 instance是因为instance不一定已经创建了,lock的内容需要非空的引用类型
    
            public static Singleton GetInstance(){//公用静态方法,外部可以调用
                lock(syncLock)
                {
                    if(instance == null)
                    {
                        instance = new Singleton();
                    }
                    return instance;
                }
            }      
    
        }
    }
    
      

    lock的作用是锁定某一代码块,让同一时间只有一个线程访问该代码块,详细参考:https://www.cnblogs.com/liuqiyun/p/9118382.html

    5.双重锁定

            public static Singleton GetInstance(){//公用静态方法,外部可以调用
                if(instance == null)//避免没必要的lock资源浪费
                {
                    lock(instance)
                    {
                        if(instance == null)//不能去掉,如果同时进入lock还是可以重复创建
                        {
                            instance = new Singleton();
                        }
                        return instance;
                    }
                }
            } 

    6.饿汉模式

      程序初始化时,就创建实例,不管用不用到。

           饿汉模式,不要显式编写线程安全代码,就可以解决多线程环境下是否安全的问题。

      解决方式使用静态初始化,代码如下:

    using System;
    
    namespace mydotnet
    {
        class Program
        {
            static void Main(string[] args)
            {
                Singleton singleton =  Singleton.GetInstance();//客户端获取实例
            }
        }  
    
        public class Singleton
        {
            private Singleton(){}//私有化构造函数,防止外部实例化,内部可以使用
    
            private readonly static Singleton instance = new Singleton();//静态初始化,不需要显式的线程安全代码
         //readonly,只能在静态初始化期间或在类的构造函数中修改,不写也没事,防止在其他方法中修改
    public static Singleton GetInstance(){ return instance; } } }

    也可以不写GetInstance方法,直接把instance设置为public,客户端直接写Singleton.instance实现更简单。

    using System;
    
    namespace mydotnet
    {
        class Program
        {
            static void Main(string[] args)
            {
                Singleton singleton =  Singleton.instance;//客户端获取实例
            }
        }  
    
        public class Singleton
        {
            private Singleton(){}//私有化构造函数,防止外部实例化,内部可以使用
    
            public readonly static Singleton instance = new Singleton();
    
        }
    }
  • 相关阅读:
    mysql_fullindex全文索引
    MySQL8.0.12安装主从复制读写分离
    备库不能应用事务&Slave_SQL_Running No
    MySQL8.0.19_Group_Replication分布式集群部署
    MySQL8.0.12_InnoDB_Cluster
    oracle12c备份恢复策略
    CentOS7.X静默安装Oracle12C
    binlog恢复数据
    windows安装多个mysql&Docker安装MySQL5.7
    论自我要求
  • 原文地址:https://www.cnblogs.com/wangliuwei/p/11804518.html
Copyright © 2020-2023  润新知