本文中出现的代码均在.net Framework RC3环境中运行通过......
大家可以看到,在上面的例程中,同步是通过等待Monitor.Pulse()来完成的。首先生产者生产了一个值,而同一时刻消费者处于等待状态,直到收到生产者的“脉冲(Pulse)”通知它生产已经完成,此后消费者进入消费状态,而生产者开始等待消费者完成操作后将调用Monitor.Pulese()发出的“脉冲”。它的执行结果很简单:
Produce: 1 Consume: 1 Produce: 2 Consume: 2 Produce: 3 Consume: 3 ... ... Produce: 20 Consume: 20 |
事实上,这个简单的例子已经帮助我们解决了多线程应用程序中可能出现的大问题,只要领悟了解决线程间冲突的基本方法,很容易把它应用到比较复杂的程序中去。
四、线程池和定时器——多线程的自动管理 在多线程的程序中,经常会出现两种情况。一种情况下,应用程序中的线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应;而另外一种情况则是线程平常都处于休眠状态,只是周期性地被唤醒。在.net framework里边,我们使用ThreadPool来对付第一种情况,使用Timer来对付第二种情况。
ThreadPool类提供一个由系统维护的线程池——可以看作一个线程的容器,该容器需要Windows 2000以上版本的系统支持,因为其中某些方法调用了只有高版本的Windows才有的API函数。你可以使用ThreadPool.QueueUserWorkItem()方法将线程安放在线程池里,该方法的原型如下:
//将一个线程放进线程池,该线程的Start()方法将调用WaitCallback代理对象代表的函数
public static bool QueueUserWorkItem(WaitCallback);
//重载的方法如下,参数object将传递给WaitCallback所代表的方法
public static bool QueueUserWorkItem(WaitCallback, object);
要注意的是,ThreadPool类也是一个静态类,你不能也不必要生成它的对象,而且一旦使用该方法在线程池中添加了一个项目,那么该项目将是没有办法取消的。在这里你无需自己建立线程,只需把你要做的工作写成函数,然后作为参数传递给ThreadPool.QueueUserWorkItem()方法就行了,传递的方法就是依靠WaitCallback代理对象,而线程的建立、管理、运行等等工作都是由系统自动完成的,你无须考虑那些复杂的细节问题,线程池的优点也就在这里体现出来了,就好像你是公司老板——只需要安排工作,而不必亲自动手。