当前位置:编程文档 >> C# >> 单件模式 Single Pattern HeadFirst学习
首页

单件模式 Single Pattern HeadFirst学习

所属类别:C#
推荐指数:★★☆
文档人气:4
本周人气:3
发布日期:2008-8-2
    定义:单件模式确保程序中一个类最多只有一个实例,并提供全局访问。 
    实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
     确定在性能和资源上的限制,然后小心的选择适当的方案实现单件,以解决多线程问题(我们必须认定所有的程序都是多线程的)。

    哪里会用到单件模式:线程池(threadpool)、缓存(cache)、对话框、处理偏好设置、注册表对象(registry)的对象、日志对象,充当打印机、显卡等设备的驱动程序对象。

    一个简单的单件类:

using System;
using System.Configuration;

namespace HeadFirstDesignPatterns.Singleton.InterestRate
{
    /// <summary>
    /// Summary description for RateSingleton.
    /// </summary>
    public class RateSingleton
    {
        private volatile static RateSingleton uniqueInstance;
        private static object syncRoot = new Object();

        private double currentRate = 
            Convert.ToDouble(ConfigurationSettings.AppSettings[\"CurrentInterestRate\"]);

        public double CurrentRate
        {
            get
            {
                return currentRate;
            }
            set
            {
                currentRate = value;
            }
        }

        private RateSingleton()
        {}

        public static RateSingleton GetInstance()
        {
            //The approach below ensures that only one instance is created and only 
            //when the instance is needed. Also, the uniqueInstance variable is 
            //declared to be volatile to ensure that assignment to the instance variable 
            //completes before the instance variable can be accessed. Lastly, 
            //this approach uses a syncRoot instance to lock on, rather than 
            //locking on the type itself, to avoid deadlocks. [Page]

            if(uniqueInstance == null)
            {
                lock (syncRoot)
                {
                    if(uniqueInstance == null)
                    {
                        uniqueInstance = new RateSingleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }
}

   主要代码:
  private volatile static RateSingleton uniqueInstance;//声明一个静态的私有的本类实例,volatile关键字见附。

  private RateSingleton(){}//提供私有的构造方法


  //用\"双重检查加锁\"减少使用同步提高单件执行的率。如果是java则要求是java5。这里与全局变量相比利用了延迟实例化的方式,这种方式对资源敏感的对象很重要。    

 public static RateSingleton GetInstance()
  {

   if(uniqueInstance == null)
   {
    lock (syncRoot)
    {
     if(uniqueInstance == null)
     {
      uniqueInstance = new RateSingleton();
     }
    }
   }
   return uniqueInstance;
  }

如果你的应用程序可以接受同步getInstance()的负担可以使用下名的版本,不过要是getInstancez在频繁允许的地方,这个方法就行不通了。因为下边的方法是每次调用都会同步的。    
   public static synchronized RateSingleton GetInstance()
{

   if(uniqueInstance == null)
   {
      uniqueInstance = new RateSingleton();
   }
   return uniqueInstance;
  }

 如果你的程序有多个类的加载器同时又使用了单件模式有时会出问题的:每个类的加载器都定义了一个命名空间,不同的类加载器可能会加载同一个类,从整个程序看,同一个类被加载了多次。如果这事发生在单件上,就会产生多个单件并存的怪异现象。解决办法:自行指定类加载器,并指定同一个。 

附:Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

       Java c#语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。 [Page]

这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。

文档说明:

     

相关文档


读取评论列表……