双检索------------------------------C#

1.双检索,用于类的访问,理论上可以提高效率。。。但是它在大多是时候是损害效率的。所以,在下面的一些代码里,记录了比双检索效率更高的方法

 public sealed class Singleton
    {
        //这是为了线程安全才这样写的。。。。这样做的代价,比在构造函数中实例化要大
        private static Object s_lock = new object();
        //这个对象引用一个单实例对象
        private static Singleton s_value = null;

        //私有化,防止外部实例化
        private Singleton()
        { }

        public static Singleton GetSingleton()
        {
            //如果对象已经创建,就直接返回(这样速度很快)
            if (s_value != null) return s_value;

            Monitor.Enter(s_lock);
            //如果还没有创建,就创建它
            if (s_value == null)
            {
                Singleton temp = new Singleton();
                //将引用保存到s_value中
                Volatile.Write(ref s_value, temp);
            }
            Monitor.Exit(s_lock);
            //返回引用
            return s_value;
        }
    }

2.双检索的升级版

 public sealed class Singleton
    {
        //这个对象引用一个单实例对象
        private static Singleton s_value = null;

        //私有化,防止外部实例化
        private Singleton()
        { }

        public static Singleton GetSingleton()
        {
            //如果对象已经创建,就直接返回(这样速度很快)
            if (s_value != null) return s_value;

            //创建一个实例对象,并把它固定下来
            Singleton temp = new Singleton();
            Interlocked.CompareExchange(ref s_value,temp,null);
            //这个技术的缺点是,,在多个线程同时访问这个方法时,会实例化多个对象。。。
            //但是,这种情况几乎不会发生。。。。
            //就算发生, 多创建的实例,之后也会被释放掉

            return s_value;
        }
    }

3。我整理了一个方法,让这个技术更通用一点

 public sealed class DoubleSearch<T> where T : class, new()
    {
        //这个对象引用一个单实例对象
        private static T s_value=null ;

        //私有化,防止外部实例化
        private DoubleSearch()
        {
            构造函数里,千万不能有副作用的代码,也不希望能被外部类调用。。。所以声明为private,并且什么也不写
        }

        public static T GetSingleton()
        {
            //如果对象已经创建,就直接返回(这样速度很快)
            if (s_value != null) return s_value;

            //创建一个实例对象,并把它固定下来
            T temp = new T();
            Interlocked.CompareExchange(ref s_value,temp,null);
            //这个技术的缺点是,,在多个线程同时访问这个方法时,会实例化多个对象。。。
            //但是,这种情况几乎不会发生。。。。
            //就算发生, 多创建的实例,之后也会被释放掉
            return s_value;
        }
    }

 

 

 

4.c#的Lazy类其实已经封装了这链中代码。。。。。但是。既然已经写出来了,就不用C#自带的了

posted on 2015-11-06 22:54  你的乐哥哥  阅读(402)  评论(0编辑  收藏  举报