参考:http://hi.baidu.com/gw820522/blog/item/8fec02cb19379b1cbe09e6ff.html
使用情况:
举例如下:
以下代码在控制台情况下,经过编译
using System;
using System.Collections.Generic;
using System.Text;
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();
Console.ReadLine();
}
static void EnterPlayer(object playerName)
{
LoadBalanceServer lbs = LoadBalanceServer.GetLoadBalanceServer();
lbs.GetLobbyServer().EnterPlayer(playerName.ToString());
}
}
//实现了SingleTon模式。负责入口,任何时候,都只有唯一实例
class LoadBalanceServer
{
private const int SERVER_COUNT = 3;
private List<LobbyServer> serverList = new List<LobbyServer>();
//任何时候,都有唯一的实例
private static volatile LoadBalanceServer lbs; //volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。
private static object syncLock = new object();
public LoadBalanceServer()
{
for (int i = 0; i < SERVER_COUNT; i++)
{
serverList.Add(new LobbyServer("LobbyServer" + i));
}
}
//获得唯一实例
public static LoadBalanceServer GetLoadBalanceServer()
{
if (lbs == null)
{
lock (syncLock) //lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
{
if (lbs == null)
{
Thread.Sleep(100);
lbs = new LoadBalanceServer();
}
}
}
return lbs;
}
//负责返回一个压力最小的LobbyServer对象
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);
}
}
}
学习知识点:
1、volatile用法
2、lock用法。同时注意,lock也可以用监视器实现,即Monitor,(Enter和Exit)他们是等效的。
使用 lock 关键字通常比直接使用 Monitor 类更可取,一方面是因为 lock 更简洁,另一方面是因为 lock 确保了即使受保护的代码引发异常,也可以释放基础监视器。这是通过 finally 关键字来实现的,无论是否引发异常它都执行关联的代码块。
3、模式本身
4、多线程调度
我的实例
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart start = new ThreadStart(Add); //启动一个新线程,做Add操作
Thread newThread = new Thread(start);
newThread.Start();
}
private void button2_Click(object sender, EventArgs e)
{
ThreadStart start = new ThreadStart(Add); //再启动一个新线程,做Add操作
Thread newThread = new Thread(start);
newThread.Start();
} 反复点击button1 和button2 ,你会发现,MessageBox.show的值是交替增加的,说明用的是同一个类实例
private void Add()
{
int temp=Singleton.GetSingletonInstance().Count++;
MessageBox.Show(temp.ToString());
Thread.Sleep(100000);
}
}
public class Singleton
{
private static volatile Singleton SingletonInstance;
private int count; //Effective C#:尽量使用属性,少使用数据成员
public int Count
{
get { return count; }
set { count = value; }
}
private static object syncLock = new object();
public static Singleton GetSingletonInstance()
{
if (SingletonInstance == null)
{
lock (syncLock)//防止两个线程同时初始化实例
{
SingletonInstance=new Singleton();
}
}
return SingletonInstance;
}
}
}