雁过请留痕...
代码改变世界

单件模式

2011-09-20 17:34  xiashengwang  阅读(254)  评论(0编辑  收藏  举报

主要是从网上找一些资料学习,练习,所以例子主要来自于网上,特别感谢牛人Terrylee,他的博客里有很多设计模式的文章,主要就是从他那里学习,讲得非常好,大家可以到哪里去看看。博客地址:http://terrylee.cnblogs.com/ 。本博客只是照着练习的例子,供个人查阅,批注。

一,概念

1) 意图

     保证一个类只有一个实例,并提供一个访问它的全局访问点。 

二,练习代码

using System;
using System.Collections.Generic;
using System.Text;

namespace CsharpBase.DesignPattern.Singleton
{
    
    /// <summary>
    /// 名称:单件模式
    /// 保证一个类只有一个实例,并提供一个对他的全局访问点
    /// </summary>
    /// <remarks>
    /// 注意:
    /// 1,单列模式的类应该只允许一个static的全局访问点,这里的允许是设计者应该
    /// 考虑的问题,是设计者的责任。而不是类成为Singleton后,只会提供一个static的静态方法
    /// 他同样可以有很多个静态的Public方法或成员。
    /// </remarks>
    class SingletonDemo
    {
        public static void Run()
        {
            CountMultiThread.MultiMain();

        }
    }

    /// <summary>
    /// 简单实现
    /// </summary>
   sealed class Singleton
    {
        private static Singleton instance;

       /// <summary>
       /// private constructor
       /// </summary>
        Singleton()
        { 
        }

        public static Singleton Instance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }

    /// <summary>
    /// 线程安全
    /// </summary>
    class Singleton2
    {
        /// <summary>
        /// private static instance
        /// </summary>
        private static Singleton2 instance;

        private static object syncLock = new object();

        /// <summary>
        /// private constructor
        /// </summary>
        Singleton2()
        { 
        }

        public static Singleton2 Instance()
        {
            lock (syncLock)
            {
                if (instance == null)
                {
                    instance = new Singleton2();
                }
            }
            return instance;
        }
    }

    /// <summary>
    /// 双重锁定 
    /// </summary>
    class Singleton3
    {
        private static Singleton3 instance;
        private static object syncLock = new object();

        Singleton3()
        { 
        }

        public static Singleton3 Instance()
        {
            if (instance == null)
            {
                lock (syncLock)
                {
                    if (instance == null)
                    {
                        instance = new Singleton3();
                    }                
                } 
            }

            return instance;
        }   
    }

    /// <summary>
    /// 静态初始化(继承)
    /// </summary>
    class Singleton4
    {
        private static readonly Singleton4 instance = new Singleton4();
        static Singleton4()
        {
            instance = new Singleton4();
        }
        protected Singleton4()
        {

        }

        public static Singleton4 Instance()
        {
            return instance;
        }

        public void WriteType()
        {
            Console.WriteLine("Object Type=" + this.GetType().Name);
        }
    }

    class SingleChild : Singleton4
    {
        private static readonly SingleChild instance = new SingleChild();
        SingleChild()
        { 
        }
        public static new SingleChild Instance()
        {
            return instance;
        }
        public void WriteMe()
        {
            Console.WriteLine("chile invoded");
        }
    }

    /// <summary>
    /// 静态初始化
    /// </summary>
    sealed class Singleton5
    {
        private static readonly Singleton5 instance = new Singleton5();

        static Singleton5()
        { 
        }
        Singleton5()
        { 
        }

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

    /// <summary>
    /// 静态初始化(延迟初始化)
    /// </summary>
    /// <remarks>
    /// 此例将静态私有变量放到Nested中返回,这样可以延迟初始化。
    /// 原因:当对类的任何成员的第一次引用是,会初始化静态成员变量。
    /// </remarks>
    sealed class Singleton6
    {

        Singleton6()
        { 
        }

        public static Singleton6 Instance()
        {
            return Nested.instance;
        }

        public static string ToStr()
        {
            return "abc";
        }
        internal class Nested
        {
            Nested()
            { 
            }

            public static Singleton6 instance = new Singleton6();
        }
    }

    #region sample
    sealed class CountSingleton
    {
        private static  readonly  CountSingleton instance = new CountSingleton();
        private static int  num =0;

        static CountSingleton()
        { 
        }

        CountSingleton()
        { 
        }

        public static CountSingleton Instance()
        {
            return instance;
        }

        public void Add()
        {
            num++;
        }

        public int GetCounter()
        {
            return num;
        }
    }

    public class CountMultiThread
    {
        private static object objLock = new object();
        private static void DoSomeWork()
        {
            CountSingleton myCounter = CountSingleton.Instance();
            //lock (objLock)
            //{
            for (int i = 0; i < 5; i++)
            {
                //这里要用lock,不然add和getcounter可能不同步。中间可能会进入其他的线程,
                //如果要保证每个线程执行五次的话lock的位置要处于for外面。
                lock (objLock)
                {
                    myCounter.Add();
                    string strResult = "theadName:" + System.Threading.Thread.CurrentThread.Name;
                    strResult += ",Counter:" + myCounter.GetCounter();
                    Console.WriteLine(strResult);
                }
            }
            Console.WriteLine("------------------------");
            //}
        }

        public static void MultiMain()
        {
            System.Threading.Thread t0 = System.Threading.Thread.CurrentThread;
            t0.Name = "thread0";

            System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork));
            t1.Name = "thread1";

            System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork));
            t2.Name = "thread2";

            System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork));
            t3.Name = "thread3";

            System.Threading.Thread t4 = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeWork));
            t4.Name = "thread4";

            t1.Start();
            t2.Start();
            t3.Start();
            t4.Start();

            DoSomeWork();
        }
    }

    #endregion

}