W2Fly

导航

设计模式------Singleton

要求:一个类只有一个实例,并且提供了一个全局的访问点。注意:客户端在调用一个类的时候,不会考虑这个类是否只能有一个实例等问题的,所以这是设计者的问题。
实现:
实现1
public sealed class Singleton
    {
        private int count = 0;
    
        //to make sure that all the instance of the class Singleton share the variable instance
     static Singleton instance = null;
     //private constructor to make sure that the client can't create the instance of the class singleton by calling the constructor
     Singleton()
     {
            count++;
        }

     //the property Instance to provide an unique access point to get the unique instance of the class Singleton
     public static Singleton Instance
     {
            get
            {
                if( instance == null )
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
       
        public int Count
        {
            get
            {
                return count;
            }
            set
            {
                count = value;
            }
        }
    };

缺点:
     对于线程来说并不安全,因为在多线程的环境下有可能得到Singleton类的多个实例.当两个线程都在判断时,因为内存模型并不能保证对象实例在第二个线程创建之前被发现.
优点:
    由于实例是在Instance属性方法内部创建的,因此类阿宽衣使用附加功能,因此类可以使用附加功能,比如对其他成员进行初始化等
     直到对象要求产生一个实例才执行实例化,这种方法称为"情性实例化",情性实例化避免了在应用程序启动时实例化不必要的   
     singleton.

实现2:
    public sealed class Singleton_Thread
    {
        static Singleton_Thread instance = null;
        static readonly object padlock = new object();

        static int count = 0;

        Singleton_Thread()
        {
            count++;
        }

        public static Singleton_Thread Instance
        {
            get
            {
                //using the lock to make sure that at the same time only one thread can get into the block int the {}
                lock(padlock)
                {
                    if(instance == null)
                    {
                        instance = new Singleton_Thread();
                    }
                    return instance;
                }
            }
        }

        public int Count
        {
            get
            {
                return count;
            }
            set
            {
                count = value;
            }
        }

    };
优点: 用lock讲创建实例的代码同一时刻只能被一个线程访问,实现了线程安全,但是每次创建都要加锁则增加了额外的开销

实现3:使用双锁
 public sealed class Singleton_DoubleLock
    {
        static Singleton_DoubleLock instance = null;
        static int count = 0;

        static readonly object padlock = new object();

        Singleton_DoubleLock()
        {
            count++;
        }

        public static Singleton_DoubleLock Instance
        {
            get
            {
                if( instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton_DoubleLock();
                        }
                    }
                }
                return instance;
            }
        }

        public int Count
        {
            get
            {
                return count;
            }
            set
            {
                count = value;
            }
        }
    };

优点:解决线程并发,同时避免每个Instance属性的调用都出现独占锁定.
         并且将实例化延迟到第一次访问对象时发生
缺点:不能实现延迟初始化

实现4:使用静态构造函数
     public sealed class Singleton_Static
    {
        //static表明是在静态初始化的时候被初始化.这个初始化操作由公用语言运行库完成
        static readonly Singleton_Static instance;
        static int count;

        static Singleton_Static()
        {
            instance = new Singleton_Static();
            count++;
        }

        Singleton_Static()
        {

        }

        public static Singleton_Static Instance
        {
            get
            {
                return instance;
            }
        }

        public int Count
        {
            get
            {
                return count;
            }
            set
            {
                count = value;
            }
        }
    };

和上面的区别: 由CLR实现变量初始化

实现5:延迟初始化
  public sealed class Singleton_Initil
    {
        static int count;

        Singleton_Initil()
        {
            count++;
        }

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

        class Nested
        {
            static Nested()
            {

            }

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

        public int Count
        {
            get
            {
                return count;
            }
           
            set
            {
                count = value;
            }
        }
    };

应用例子:
简单计数器,四个线程同时进行计数.

//实现一个单个计数器,singleton设计模式,所以只有一个计数器供四个线程使用.
 public class CountSingleton
    {
        static CountSingleton uniCounter = new CountSingleton();
        private int totNum = 0;

        private CountSingleton()
        {
            Thread.Sleep(2000);
        }
        public static CountSingleton Instance()
        {
            return uniCounter;
        }

        public void Add()
        {
            totNum++;
        }

        public int GetCounter()
        {
            return totNum;
        }
    };

    public class CountMutiThread
    {
        public CountMutiThread()
        {

        }

        //每个线程执行的操作就是进行计数,并输出当前的计数值
        public static void DoSomeWork()
        {
            string results = "";
            CountSingleton MyCounter = CountSingleton.Instance();
            for(int i = 1; i < 5; i++ )
            {
                MyCounter.Add();
                results += "线程";
                results += Thread.CurrentThread.Name.ToString() + "--> ";
                results += "当前的计数";
                results += MyCounter.GetCounter().ToString();
                results += "\n";

                Console.WriteLine(results);

                results = "";
            }
        }

        //创建四个线程并开始运行
        public void StartMain()
        {
            Thread thread0 = Thread.CurrentThread;
            thread0.Name = "Thread 0";
            Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
            thread1.Name = "Thread 1";
           
            Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
            thread2.Name = "Thread 2";
            Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
            thread3.Name = "Thread 3";
            thread1.Start();
            thread2.Start();           
            DoSomeWork();           
            thread3.Start();
        }
    };
    class CountClient
    {
        static void Main(string[] args)
        {
            CountMutiThread cmt = new CountMutiThread();
            cmt.StartMain();
            Console.ReadLine();
        }
    }
      

posted on 2007-02-07 13:43  像大海一样......  阅读(164)  评论(0)    收藏  举报