单例模式

一、饿汉式->单例一开始就初始化好,只要有请求就给,此时的无论多少个请求都指向同一个单例。这里也可以将初始化操作 _instance = new BufferHandler() 放在构造函数中。

        private static BufferHandler _instance = new BufferHandler();
        public static BufferHandler GetOneIns()
        {
            return _instance;
        }

二、懒汉式->单例只有在请求的时候才初始化并返回给请求者,如果是多线程请求有可能请求到的两个是不同的单例,这样就会线程不安全。

如何理解懒汉式:即延迟加载,饿汉式在该类初始化时即初始化该单例,而懒汉式可以发现只有在请求此单例时才会被初始化,故称懒汉式(lazy_load);

        private static BufferHandler _instance;
        public static BufferHandler GetOneIns()
        {
            if (_instance == null) _instance = new BufferHandler();
            return _instance;
        }

三、内部静态类

懒汉式的延迟加载思想也可以应用于饿汉式中,此时需要借用一个内部静态类来实现。既实现了延迟创建,又保证了单例的线程安全。

        private static BufferHandler _instance;
        private static class BufferInstanceInstanceCreater
        {
            public static readonly BufferHandler Instance = new BufferHandler();
        }

        public static BufferHandler GetOneIns()
        {
            return BufferInstanceInstanceCreater.Instance;
        }

 

四、双重锁线程同步

        public static object _inslock = new object();
        private static BufferHandler _instance;
        public static BufferHandler GetOneIns()
        {
            if (_instance == null)
            {
                lock (_inslock)
                {
                    if (_instance == null)
                        _instance = new BufferHandler();
                }
            }
            return _instance;
        }

为什么要用双重锁?

第一层 if (instance == null)是为了减少线程对同步锁锁的竞争,第二层if(instance==nul)是保证单例。

即第一层判断,如果单例已经存在的话就可以直接获得已经创建好的单例(即已经被缓存起来了),不需要进行同步锁lock操作,即减少竞争同步锁;第二步则是如果进程1同步锁时已经有另外一个进程2在占用同步锁,意味着进程2在申请单例。那么当同步锁释放时,进程1获得了同步锁资源,而此时单例也被创建好了,因此此时也需要一次判断。

posted on 2021-01-11 17:18  freden  阅读(76)  评论(0编辑  收藏  举报