高手进,分析一个线程同步代码片段优劣
代码实现的功能如下:一个生产者线程,一个消费者程,生产一个产品,消费一个,再生产,再消费...
A版代码如下:
static void ProduceOneA()
{
lock (locker)
{
while (true)
{
if (isHave)
Monitor.Wait(locker);
Thread.Sleep(1000);
Console.WriteLine("生产一个");
isHave = true;
Monitor.Pulse(locker);
}
}
}
static void ConsumeOneA()
{
lock (locker)
{
while (true)
{
if(!isHave)
Monitor.Wait(locker);
Thread.Sleep(500);
Console.WriteLine("消费一个");
isHave = false;
Monitor.Pulse(locker);
}
}
}
static object locker = new object();
volatile static bool isHave = false;
static void Main(string[] args)
{
new Thread(ProduceOneA).Start();
new Thread(ConsumeOneA).Start();
}
是比较常见的lock{while(){}}结构,B版代码如下:
static void ProduceOneB()
{
while (true)
{
lock (locker)
{
if (isHave)
Monitor.Wait(locker);
Thread.Sleep(1000);
Console.WriteLine("生产一个");
isHave = true;
Monitor.Pulse(locker);
}
}
}
static void ConsumeOneB()
{
while (true)
{
lock (locker)
{
if (!isHave)
Monitor.Wait(locker);
Thread.Sleep(500);
Console.WriteLine("消费一个");
isHave = false;
Monitor.Pulse(locker);
}
}
}
注意这里变成了while(){lock{}},这两个版本的代码都能达到目的,但孰优孰劣,高手给分析下,个人感觉lock{}里的同步代码应该越短约好如B版代码,但B版的结构频繁调用lock{}又是一个问题...
------解决方案--------------------C# code
void ProduceOneA()
{
while (Interlocked.Read(ref bRun) == 1)
{
try
{
ProduceHandler.waitone();
Console.WriteLine("生产一个");
ConsumeHandler.set();
}
finally
{
Thread.Sleep(1000);
}
}
}
void ConsumeOneA()
{
while (Interlocked.Read(ref bRun) == 1)
{
try
{ ConsumeHandler.waitone();
Console.WriteLine("消费一个");
ProduceHandler.set();
}
finally
{
Thread.Sleep(1000);
}
}
}
}
private ReaderWriterLock m_RWHandlers = new ReaderWriterLock();
long m_Run = 0;
AutoResetEvent m_ConsumeHandler = new AutoResetEvent(false);
AutoResetEvent m_ProduceHandler = new AutoResetEvent(true);
static void Main(string[] args)
{
Interlocked.Exchange(ref m_Run, 1);
new Thread(new threadstart(ProduceOneA)).Start();
new Thread(new threadstart(ConsumeOneA)).Start();
}