设计模式创建型之单例模式

单例就是在应用程序中保证类型只有一个实例。

创建一个简单的单例,代码如下

 public class Singleton
    {
        private Singleton() //构造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null;

        //对外提供一个获取实例的方法
        public static Singleton CreateInstance()
        {
            if (_singleton == null)
            {
                _singleton= new Singleton();
            }
            return _singleton;
        }
    }

这样存在的问题是多线程时,线程不安全,升级如下

 public class Singleton
    {
        private Singleton() //构造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null;

        private static object _lockObject = new object();
        //对外提供一个获取实例的方法
        public static Singleton CreateInstance()
        {
            lock (_lockObject)//确保任意时刻只有一个线程访问
            {
                if (_singleton == null)
                {
                    _singleton = new Singleton();
                }
            }
            return _singleton;
        }
    }

线程 安全,但是有性能问题,继续升级如下

 public class Singleton
    {
        private Singleton() //构造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null;

        private static object _lockObject = new object();
        //对外提供一个获取实例的方法
        public static Singleton CreateInstance()
        {
            if (_singleton == null) //对像不为空时直接返回,不用排队取锁,提高性能
            {
                lock (_lockObject)//确保任意时刻只有一个线程访问
                {
                    if (_singleton == null)
                    {
                        _singleton = new Singleton();
                    }
                }
            }
            
            return _singleton;
        }
    }

这样 通过双if加lock ,就实现了一个懒汉式的单例。

懒汉式 :需要才创建实例,延迟加载

饿汉式 :第一时间创建实例,类加载就马上创建 

接下来实现两种饿汉式 的单例

1 静态方法中初始化对象

public class Singleton
    {
        private Singleton() //构造私有化,防止外部New
        {
            
        }
      
        private static Singleton _singleton = null;

        //静态构造函数:由CLR保证单例,程序第一次使用这个类型前被调用,且只调用一次
        static Singleton()
        {
            _singleton = new Singleton();
        }

        //对外提供一个获取实例的方法
        public static Singleton CreateInstance()
        {            
            return _singleton;
        }
    }

 

2  静态字段赋值

public class Singleton
    {
        private Singleton() //构造私有化,防止外部New
        {
            
        }

        //静态字段:在第一次使用这个类之前,由CLR保证,初始化且只初始化一次
        private static Singleton _singleton = new Singleton();

        //对外提供一个获取实例的方法
        public static Singleton CreateInstance()
        {            
            return _singleton;
        }
    }

单例模式创建的实例不会自动释放内存,会长时间占据内存空间。适用场景线程池,数据库连接池,计数器/流水号生成器,配置文件读取,IOC容器。

posted @ 2020-08-12 21:01  一叶青城  阅读(129)  评论(0编辑  收藏  举报