本节内容:
使用两个线程来分别模拟生产者和消费者。
使用 Monitor 来模拟管理员。管理员在生产过剩时告诉生产者暂停生产,消费过剩时告诉消费者暂停消费。
例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
///线程同步模拟
namespace MultiThread
{
class Problem
{
static int[] buffers=new int[3];
static int readLocation=0;
static int writeLocation = 0;
static object locker=new object();
static int blankCount = 3;
private int Buffer
{
get
{
lock (locker)
{
if (blankCount >= 3)
{
Console.WriteLine("buffers are all empty now! Consumer waits!");
Monitor.Wait(locker);
}
readLocation = readLocation % 3;
int buffer = buffers[readLocation];
buffers[readLocation] = 0;
readLocation++;
blankCount++;
Monitor.Pulse(locker);
return buffer;
}
}
set
{
lock (locker)
{
if (blankCount <= 0)
{
Console.WriteLine("buffers are all full now! Producer waits!");
Monitor.Wait(locker);
}
writeLocation = writeLocation % 3;
buffers[writeLocation] = value;
writeLocation++;
blankCount--;
Monitor.Pulse(locker);
}
}
} // www.jb200.com
void Produce()
{
for (int i = 0; i < 11; i++)
{
lock (locker)
{
this.Buffer = i+1;
Console.WriteLine("Produer has produce a " + (i+1) + " in buffers");
Thread.Sleep(1000);
}
}
}
void Consume()
{
for (int i = 0; i < 11; i++)
{
lock (locker)
{
Console.WriteLine("Consumber has consume a " + this.Buffer + " from buffers");
Thread.Sleep(1000);
}
}
}
static void Main(string[] args)
{
Problem p = new Problem();
Thread producer = new Thread(p.Produce);
Thread consumer = new Thread(p.Consume);
producer.Name = "producer";
producer.Start();
consumer.Name = "consumer";
consumer.Start();
Console.ReadKey();
}
}
}
代码说明:
锁对象并不保证线程间会同步。
生产者消费者都拥有锁,锁就没有作用,线程执行时会忽略锁的存在继续执行被锁住的代码。
只有管理员通过这个锁来通知生产者和消费者时,这个锁才会起到阻止线程执行的作用。
锁的目的只是保证这个代码块中的变量的值是最新的,但不保证别的线程不会去修改这个变量。
锁可以是任意对象,但要保证消费和生产这一对操作所使用的锁对象是同一个对象。