Thread-safe Singleton load balancer example class with random selection.
using System;
using System.Collections.Generic;
using System.Threading;
namespace SingletonExample
{
/// <summary>
/// MainApp startup class for Real-World
/// Singleton Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// Load balance 15 server requests
LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
for (int i = 0; i < 15; i++)
{
string server = balancer.Server;
Console.WriteLine("Dispatch Request to: " + server);
}
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Singleton' class
/// </summary>
class LoadBalancer
{
static LoadBalancer instance;
List<string> servers = new List<string>();
Random random = new Random();
// Lock synchronization object
private static object locker = new object();
// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
servers.Add("ServerI");
servers.Add("ServerII");
servers.Add("ServerIII");
servers.Add("ServerIV");
servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (instance == null)
{
lock (locker)
{
if (instance == null)
{
instance = new LoadBalancer();
}
}
}
return instance;
}
// Simple, but effective random load balancer
public string Server
{
get
{
int r = random.Next(servers.Count);
return servers[r].ToString();
}
}
}
}