为了理解监视器,我实现了以下code.But,我不确定代码是否是线程安全的。
namespace MonitorExample
{
public delegate void WaterLevelInformer(object sender,WaterLevelArgs e);
class WaterLevelListener
{
//listener will print information
// when WaterTank is reaching its empty level or full
public void ShowResult(object sender, WaterLevelArgs e)
{
Console.WriteLine("Water Level is :{0}", e.Level);
}
}
class WaterTank
{
//starting level is empty
static int level=0;
//capacity of the WaterTank is 2000 liters
const int capacity = 2000;
private WaterLevelListener lst = new WaterLevelListener();
public event WaterLevelInformer levelHandler;
public WaterTank(WaterLevelListener lstn)
{
this.lst = lstn;
this.levelHandler +=new WaterLevelInformer(lst.ShowResult);
}
public void FillWater()
{
lock (this)
{
if (level >= capacity)
{
Monitor.Wait(this);
}
Console.WriteLine("....WaterTank is gettig filled...");
for (int i = 100; i <= 2000; i+=100)
{
Console.WriteLine("Current Water Level {0}", i);
level = i;
Thread.Sleep(1000);
if (i == 1700)
{
WaterLevelInformation(level);
Thread.Sleep(1000);
}
}
Monitor.Pulse(this);
}
}
public void ConsumeWater()
{
lock (this)
{
if (level<=0)
{
Monitor.Wait(this);
}
Console.WriteLine("...Water is being consumed....");
for (int i =2000; i >= 0; i -= 100)
{
Console.WriteLine("Current Water Level {0}", i);
Thread.Sleep(1000);
level = i;
if (i == 100)
{
WaterLevelInformation(i);
Thread.Sleep(1000);
}
}
Monitor.Pulse(this);
}
}
//WaterLevelInformation is used to raise the event
// When WaterTank reaching its empty level
//or WaterTank is full
public void WaterLevelInformation(int i)
{
if (levelHandler != null)
{
WaterLevelArgs waterArgs=new WaterLevelArgs(i);
levelHandler(this,waterArgs);
}
}
}
// WaterLevelArgs class stores the level of
// the water
public class WaterLevelArgs : EventArgs
{
public int Level
{
get;
set;
}
public WaterLevelArgs(int level)
{
Level = level;
}
}
class WaterLevelSimulator
{
static void Main()
{
WaterLevelListener lst = new WaterLevelListener();
WaterTank tnk = new WaterTank(lst);
Thread thd1 = new Thread(new ThreadStart(tnk.ConsumeWater));
Thread thd2 = new Thread(new ThreadStart(tnk.FillWater));
thd1.Start();
thd2.Start();
Console.ReadKey();
}
}
}问题:
1)以上代码是线程安全的吗?
2)随着C# 2.0和3.0引入了Action<>、Predicate<>、lambda,我如何改进我的代码?
3)为了使用发布者,观察者模式,我可以遵循什么是最好的模式,我的意思是,我是否需要为(i)自定义EventArgs (ii)侦听器(iii)发布者(iv)链接器-(链接侦听器,发布者,自定义EventArgs)设计单独的类?
发布于 2009-11-26 23:22:26
微软不推荐使用lock(this) (也就是Monitor.Wait(this)) (参见MSDN on lock-Keyword)。
你应该使用一个单独的锁定对象,比如string变量或者其他对象--这对于int之类的简单类型是不起作用的。
发布于 2009-11-26 21:53:58
这是家庭作业吗?不管怎样..。
1)在快速浏览之后,代码看起来像是threadsafe,但非常同步,以至于线程实际上不会同时执行任何工作。因此,对于这段代码,您也可以使用一个带有循环的线程。
2)现在不用担心这一点,真正的改进不仅仅来自语法(在这种情况下,这主要是那些构造将为您带来的)。
3)我不清楚你需要什么。
发布于 2009-11-26 22:01:24
你应该阅读下面这篇关于锁定对象的文章(并点击文章顶部评论中的链接):
http://haacked.com/archive/2005/04/12/NeverLockThis.aspx
https://stackoverflow.com/questions/1803734
复制相似问题