Welcome

首页 / 软件开发 / C# / 无废话C#设计模式之二:Singleton

无废话C#设计模式之二:Singleton2010-01-13 博客园 lovecherry意图

保证一个类只有一个实例,并提供访问它的全局访问点。

场景

我们现在要做一个网络游戏的服务端程序,需要考虑怎么样才能承载大量的用户。在做WEB程序的时候有各种负载均衡的方案,不管是通过硬件实现还是软件实现,基本的思想就是有一个统一的入口,然后由它来分配用户到各个服务器上去。

需要考虑的问题是,即使在多线程的并发状态下,用户只能通过一个唯一的入口来分配,由此引入了Singleton模式来实现这个唯一的入口。

示例代码

using System;

using System.Collections.Generic;

using System.Threading;

namespace SingletonExample

{

class Program

{

static void Main(string[] args)

{

ParameterizedThreadStart ts = new ParameterizedThreadStart(EnterPlayer);

for (int i = 0; i < 20; i++)

{

Thread t = new Thread(ts);

t.Start("player" + i);

}

LoadBalanceServer.GetLoadBalanceServer().ShowServerInfo();

}

static void EnterPlayer(object playerName)

{

LoadBalanceServer lbs = LoadBalanceServer.GetLoadBalanceServer();

lbs.GetLobbyServer().EnterPlayer(playerName.ToString());

}

}

class LoadBalanceServer

{

private const int SERVER_COUNT = 3;

private List<LobbyServer> serverList = new List<LobbyServer>();

private static volatile LoadBalanceServer lbs;

private static object syncLock = new object();

private LoadBalanceServer()

{

for (int i = 0; i < SERVER_COUNT; i++)

{

serverList.Add(new LobbyServer("LobbyServer" + i));

}

}

public static LoadBalanceServer GetLoadBalanceServer()

{

if (lbs == null )

{

lock (syncLock)

{

if (lbs == null )

{

Thread.Sleep(100);

lbs = new LoadBalanceServer();

}

}

}

return lbs;

}

public LobbyServer GetLobbyServer()

{

LobbyServer ls = serverList[0];

for (int i = 1; i < SERVER_COUNT; i++)

{

if (serverList[i].PlayerList.Count < ls.PlayerList.Count)

ls = serverList[i];

}

return ls;

}

public void ShowServerInfo()

{

foreach (LobbyServer ls in serverList)

{

Console.WriteLine("=================" + ls.ServerName + "=================");

foreach (string player in ls.PlayerList)

{

Console.WriteLine(player);

}

}

}

}

class LobbyServer

{

private List<string> playerList = new List<string>();

public List<string> PlayerList

{

get { return playerList; }

}

private string serverName;

public string ServerName

{

get { return serverName; }

}

public LobbyServer(string serverName)

{

this.serverName = serverName;

}

public void EnterPlayer(string playerName)

{

playerList.Add(playerName);

}

}

}