Singleton PAttern

 

Comments

 

The classic solution to this problem is to use mutual exclusion on the class that indicates that the object is being instantiated.

 

Code

 

1.	using System;
2.	using System.Collections.Generic;
3.	using System.Threading;
4.	 
5.	namespace DoFactory.GangOfFour.Singleton.RealWorld
6.	{
7.	  /// 
8.	  /// MainApp startup class for Real-World 
9.	  /// Singleton Design Pattern.
10.	  /// 
11.	  class MainApp
12.	  {
13.	    /// 
14.	    /// Entry point into console application.
15.	    /// 
16.	    static void Main()
17.	    {
18.	      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
19.	      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
20.	      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
21.	      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
22.	 
23.	      // Same instance?
24.	      if (b1 == b2 && b2 == b3 && b3 == b4)
25.	      {
26.	        Console.WriteLine("Same instance\n");
27.	      }
28.	 
29.	      // Load balance 15 server requests
30.	      LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
31.	      for (int i = 0; i < 15; i++)
32.	      {
33.	        string server = balancer.Server;
34.	        Console.WriteLine("Dispatch Request to: " + server);
35.	      }
36.	 
37.	      // Wait for user
38.	      Console.ReadKey();
39.	    }
40.	  }
41.	 
42.	  /// 
43.	  /// The 'Singleton' class
44.	  /// 
45.	  class LoadBalancer
46.	  {
47.	    private static LoadBalancer _instance;
48.	    private List _servers = new List();
49.	    private Random _random = new Random();
50.	 
51.	    // Lock synchronization object
52.	    private static object syncLock = new object();
53.	 
54.	    // Constructor (protected)
55.	    protected LoadBalancer()
56.	    {
57.	      // List of available servers
58.	      _servers.Add("ServerI");
59.	      _servers.Add("ServerII");
60.	      _servers.Add("ServerIII");
61.	      _servers.Add("ServerIV");
62.	      _servers.Add("ServerV");
63.	    }
64.	 
65.	    public static LoadBalancer GetLoadBalancer()
66.	    {
67.	      // Support multithreaded applications through
68.	      // 'Double checked locking' pattern which (once
69.	      // the instance exists) avoids locking each
70.	      // time the method is invoked
71.	      if (_instance == null)
72.	      {
73.	        lock (syncLock)
74.	        {
75.	          if (_instance == null)
76.	          {
77.	            _instance = new LoadBalancer();
78.	          }
79.	        }
80.	      }
81.	 
82.	      return _instance;
83.	    }
84.	 
85.	    // Simple, but effective random load balancer
86.	    public string Server
87.	    {
88.	      get
89.	      {
90.	        int r = _random.Next(_servers.Count);
91.	        return _servers[r].ToString();
92.	      }
93.	    }
94.	  }
95.	}