码迷,mamicode.com
首页 > Windows程序 > 详细

《Head First设计模式》C#实现(六)——单例模式

时间:2015-09-17 10:12:22      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

 

构成:

1.私有的构造函数

2.私有静态的实例

3.返回实例的静态方法

  public class Singleton
    {
        private static Singleton uniqueInstance = new Singleton();
        private Singleton() { Console.WriteLine("this is a new singleton"); }
        public static Singleton getInstance()
        {
            if (uniqueInstance == null)
            {
                return uniqueInstance;
            }
            return uniqueInstance;
        }
    }

 

这种叫做饿汉模式,实例在类加载时就创建了,缺点是如果实例如果消耗大量的资源而没有使用就会造成浪费,另一种懒汉模式,实例在被使用时才创建,

  public class Singleton
    {
        private static Singleton uniqueInstance;
        private Singleton() { Console.WriteLine("this is a new singleton"); }
        public static Singleton getInstance()
        {
            if (uniqueInstance == null)
            {
                return uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
    }

但是这不是线程安全的

例如

class Program {
     
        static void Main(string[] args) {
            while (true) {
                Thread t1 = new Thread(Test);
                t1.Start();
            }
        }
        static void Test() {
            Singleton s = Singleton.getInstance();
        }
       
    }

执行的结果有可能是这样

技术分享

程序创建了多个实例,这不是我们想要的结果,原因是某个线程if (uniqueInstance == null)语句执行后让出了使用权,当它重新获得CPU使用权的时候,可能别的CPU已经创建了实例,而它并不知道,继续执行return uniqueInstance= new Singleton();导致出现多个实例。

因此,要为方法加锁

  public class Singleton
    {
        private static Singleton uniqueInstance;
        private Singleton() { Console.WriteLine("this is a new singleton"); }
        private static readonly object syncRoot = new object();
        public static Singleton getInstance()
        {
            lock (syncRoot)
            {
                if (uniqueInstance == null)
                {
                      return uniqueInstance = new Singleton();
                }
            }

            return uniqueInstance;
        }
    }

但是这又带来了一个问题,在实例已经创建完成了,但还是会有大量的线程卡在lock (syncRoot),它们都还会尝试创建实例,这降低了性能

为此,还要为此方法创建另外一个验证

 public static Singleton getInstance()
        {
            if (uniqueInstance == null)
            {
                lock (syncRoot)
                {
                    if (uniqueInstance == null)
                    {
                       return uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }

此时,当实例已经创建完成之后,各线程不再访问临界区,提高了性能

《Head First设计模式》C#实现(六)——单例模式

标签:

原文地址:http://www.cnblogs.com/castdream/p/4814151.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!