Fighting Ant

Ant can be great while elephant can be chickenshit

导航

传说中的Singleton....

Posted on 2010-06-03 18:22  Nillson  阅读(250)  评论(1编辑  收藏  举报

最近做了一些WCF的项目,在客户端利用ChannelFactory创建一个Channel时会希望这个ServiceChannel在整个客户端中是唯一的。于是乎用了以下的代码,并一度为自己的聪明才智而欢欣鼓舞

 

代码
 1         /// <summary>
 2         /// service for Boss service action
 3         /// </summary>
 4         private IEBService _service;
 5 
 6         /// <summary>
 7         /// channel factories wich can create a channel for IEBService
 8         /// </summary>
 9         private ChannelFactory<IEBService> _channelFactory;
10 
11         public IEBService Service
12         {
13             get
14             {
15                 if (_service == null)
16                 {
17                     BasicHttpBinding binding = new BasicHttpBinding();
18                     binding.MaxReceivedMessageSize = EBSettings.MessageCapacity;
19                     binding.ReaderQuotas.MaxArrayLength = EBSettings.MessageCapacity;
20                     binding.SendTimeout = TimeSpan.FromHours(1);
21                     binding.ReceiveTimeout = TimeSpan.FromHours(1);
22                     string serviceUrl = string.Format(EBSettings.EBServiceURLPattern, MachineName, EBSettings.EBServicePort);
23                     this._channelFactory = new ChannelFactory<IEBService>(binding, serviceUrl);
24                     _service = _channelFactory.CreateChannel();
25                 }
26                 return _service;
27             }
28         }
29 


后来才知道这就是传说中的Singleton 模式 ~~。更可悲的是我曾亲口对一个哥们说过:”Singleton模式?什么东西?“ 看来人不能傻到这种程度....

补课>>

 

 

代码
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace ConsoleApplication1
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             SingletonClass.Instance.Print(); // The way to call the instance
13         }
14     }
15 
16     class SingletonClass
17     {
18         private SingletonClass()
19         {
20             // do nothing but override the contribute method to avoid new an instant outside this class
21         }
22 
23         private static SingletonClass _instance = null;
24 
25         /// <summary>
26         /// The only instance that use to return
27         /// </summary>
28         public static SingletonClass Instance
29         {
30             // Client can only access from here and this will make sure the same SingletonClass instance be returned
31             get
32             {
33                 if (_instance == null)
34                 {
35                     _instance = new SingletonClass();
36                 }
37                 return _instance;
38             }
39             
40             private set
41             {
42             }
43         }
44 
45         public void Print()
46         {
47             Console.WriteLine("I'm the only instance of Singleton Class");
48         }
49     }
50 }
51 

然而据可靠资料(MSDN)显示,这种做法在遇到多线程的时候会出现问题,即在当两个线程同时尝试创建该类的实例时,他们的初始条件(_instance == null)可能都符合,所以每个线程会试图去创建一个该类的实例。这种情况肯定是咱家不希望看到的,但是具体会出现啥样的情况需要以实践来检验。对此MSDN没有给出官方的说法~~,但是一种多线程下的Singleton模式也由此诞生了

 

代码
 1 using System;
 2 
 3 public sealed class Singleton
 4 {
 5    private static volatile Singleton instance;
 6    private static object syncRoot = new Object();
 7 
 8    private Singleton() {}
 9 
10    public static Singleton Instance
11    {
12       get 
13       {
14          if (instance == null
15          {
16             lock (syncRoot) 
17             {
18                if (instance == null
19                   instance = new Singleton();
20             }
21          }
22 
23          return instance;
24       }
25    }
26 }
27 

这段代码在实例化之前加了一把”锁“让跑在它后边的线程暂时进不来,也就解决了上一段代码所可能存在的问题。

官方资料给的很清楚,不翻译了

 http://msdn.microsoft.com/en-us/library/ff650316.aspx