实现Singleton模式

常见的设计模式有许多,不过在面试过程中要应聘者完整的实现一个非Singleton莫属,但如何写好Singleton还是有许多要注意的地方的。

简单的单线程解法:

public sealed class Singleton1
{
    private Singleton1()
    {
    }

    private static Singleton1 instance = null;
    public static Singleton1 Instance
    {
        get
        {
            if (instance == null)
                instance = new Singleton1();

            return instance;
        }
    }
}

适应多线程但效率不高的解法:这样每次访问都要加锁,这是非常耗时的。

public sealed class Singleton2
    {
        private Singleton2()
        {
        }

        private static readonly object syncObj = new object();

        private static Singleton2 instance = null;
        public static Singleton2 Instance
        {
            get
            {
                lock (syncObj)
                {
                    if (instance == null)
                        instance = new Singleton2();
                }

                return instance;
            }
        }
    }

避免不必要的加锁操作:只有在没实例化时加锁判断,否则直接返回实例

public sealed class Singleton3
    {
        private Singleton3()
        {
        }

        private static object syncObj = new object();

        private static Singleton3 instance = null;
        public static Singleton3 Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncObj)
                    {
                        if (instance == null)
                            instance = new Singleton3();
                    }
                }

                return instance;
            }
        }
    }

C#特性的解法:利用静态构造函数,不过有个缺点是不是第一次调用属性Instance时创建实例,而是第一次用到Singleton4时就会被创建,例如调用静态方法Print时就会创建,这样会过早创建实例,从而降低内存使用率。

(对于较小的对象,可以忽略这点)

public sealed class Singleton4
    {
        private Singleton4()
        {
        }

        public static void Print()
        {
            Console.WriteLine("Singleton4 Print");
        }

        private static Singleton4 instance = new Singleton4();
        public static Singleton4 Instance
        {
            get
            {
                return instance;
            }
        }
    }

按需创建实例:避免了Singleton4的过早创建问题,通俗的讲就是再套多一层,利用嵌套类的静态构造函数来构造这个实例,而这个嵌套类是不包含任何方法的且是私有的,所以就避免了调用Singleton的静态方法就把实例提前创建了的问题。

public sealed class Singleton5
    {
        Singleton5()
        {
        }

        public static void Print()
        {
            Console.WriteLine("Singleton5 Print");
        }

        public static Singleton5 Instance
        {
            get
            {
                return Nested.instance;
            }
        }

        class Nested
        {
            static Nested()
            {
            }

            internal static readonly Singleton5 instance = new Singleton5();
        }
    }

补充说明:在C++下实现Singleton就麻烦得多了,实现垃圾回收需要用到auto_ptr,解决线程安全的问题需要使用到第三方的线程库(或者自己写),例如boost库。

posted @ 2013-10-21 17:51  Linka  阅读(223)  评论(0编辑  收藏  举报