然后在下面这个类MonitorSample的Main()函数中我们要做的就是创建两个线程分别作为生产者和消费者,
使用CellProd.ThreadRun()方法和CellCons.ThreadRun()方法对同一个Cell对象进行操作。
public class MonitorSample
{
public static void Main(String[] args)
{int result = 0;
//一个标志位,如果是0表示程序没有出错,如果是1表明有错误发生
Cell cell = new Cell( );
//下面使用cell初始化CellProd和CellCons两个类,生产和消费次数均为20次
CellProd prod = new CellProd(cell, 20);
CellCons cons = new CellCons(cell, 20);
Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
//生产者线程和消费者线程都已经被创建,但是没有开始执行
try{
producer.Start( );
consumer.Start( );
producer.Join( );
consumer.Join( );
Console.ReadLine();
}catch (ThreadStateException e){
//当线程因为所处状态的原因而不能执行被请求的操作
Console.WriteLine(e);
result = 1;
}catch (ThreadInterruptedException e){
//当线程在等待状态的时候中止
Console.WriteLine(e);
result = 1;
}
//尽管Main()函数没有返回值,但下面这条语句可以向父进程返回执行结果
Environment.ExitCode = result;
}
}
大家可以看到,在上面的例程中,同步是通过等待Monitor.Pulse()来完成的。
首先生产者生产了一个值,而同一时刻消费者处于等待状态,直到收到生产者的“脉冲(Pulse)”通知它生产已经完成,此后消费者进入消费状态,而生产者开始等待消费者完成操作后将调用Monitor.Pulese()发出的“脉冲”。
它的执行结果很简单:
Produce: 1
Consume: 1
Produce: 2
Consume: 2
Produce: 3
Consume: 3
...
...
Produce: 20
Consume: 20
事实上,这个简单的例子已经帮助我们解决了多线程应用程序中可能出现的大问题,只要领悟了解决线程间冲突的基本方法,
很容易把它应用到比较复杂的程序中去。
四.小结
这篇文章之所以叫做《C#多线程机制初探》是因为它只涉及到多线程机制的一个角落--什么是线程,如何创建和使用线程,
怎样进行线程的同步和通讯等等,而没有讲到C#中其它与多线程相关的内容如使用线程池(ThreadPool)实现异步I/O,
使用定时器(Timer)定时触发线程等等,对于线程的其它典型问题如死锁和饥饿也没有明确的解决。