之乎者也,阿弥陀佛

软件设计的原则就是,化繁为简,化难为易,把人的思维集中在简单的领域,然后通过有序的组合实现复杂的逻辑。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
目的:
保证一个类仅有一个实例,并提供一个访问它的全局访问点

实现方式:

1.最简单的方式

 public class Singleton
    {
        private static Singleton _instance;
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {  
                return _instance == null ? (new Singleton()) : _instance;
            }
        }       
    }

 上面代码保证3点:第一,类不能被实例化(私有构造函数);第二,类不能被继承(私有构造函数);第三,提供一个全局访问的静态属性。

保证以上3点,单线程里我们就可以确保一个类只能提供一个实例,但是多线程下就不能确保了,我们看一下代码:

 

View Code
 class Program
    {
        static void Main(string[] args)
        {
            MultWork multThread = new MultWork();
            multThread.StartMultThread();
            Console.ReadLine();
        }
    }
    public class Singleton
    {
        private static Singleton _instance;
        private static readonly Object padlock = new object();
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {                
                return _instance == null ? (new Singleton()) : _instance;
            }

        }

   }
    public class MultWork
    {
        private static readonly Object padlock = new object();
        /// <summary>
        
/// 线程工作
        
/// </summary>
        public static void DoSomeWork()
        {
            ///构造显示字符串
            string results = string.Empty;
            ///创建一个Sigleton实例
            Singleton MyCounter = Singleton.Instance;
            ///循环调用四次
            for (int i = 1; i < 5; i++)
            {               
                results += "线程";
                results += Thread.CurrentThread.Name.ToString();
                results += "\n";
            }
        }
        public void StartMultThread()
        {
            Thread thred0 = Thread.CurrentThread;
            thred0.Name = "主线线程";
            Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
            thread1.Name = "thread1";
            thread1.Start();
            Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
            thread2.Name = "thread2";
            thread2.Start();
            Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
            thread3.Name = "thread3";
            thread3.Start();
            DoSomeWork();
        }

 我们新开了3个线程(包含主线程共4个线程),发现单例居然被实例化了4次,也就是说:每个线程独立实例化了Singleton,这可违背单例模式的初衷

 

2.惰性实例化

 为了解决线程的安全问题,我们可以在单例中加一个锁,保证同一时刻只能有一个线程访问,一旦存在实例,将不再实例化单例类,重新设计单例类代码如下:

 

View Code
public class Singleton
    {
        private static Singleton _instance;
        private static readonly Object padlock = new object();
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {
                lock (padlock)
                    if (_instance == null)
                        _instance = new Singleton();
                return _instance;

            }

        }
}

 这样运行代码后发现无论启动多少个线程,都能保证类只有一个实例

 3.类型构造器方法(或者称为静态构造器法)

这种做法的优点是:让线程的安全性交给CLR来负责,这也是.NET中推荐的一种单例设计方式,代码如下:

 

View Code
 public  class Singleton
    {
        private static  Singleton _instance =null;        
        static Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        private Singleton()
        {
        }
        public static Singleton Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Singleton();
                return _instance;

            }
        }     
    }

总之,以上就我在项目中经常使用的方式,当然还有其他更多的实现方式,你可以参看园子中其他大牛的文章,比如TerryLee的设计模式系列:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html


 

 

posted on 2012-02-09 16:15  搏击的小船  阅读(314)  评论(0编辑  收藏  举报