首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Dotnet频道
中国IT教育
Google
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> C# >> 正文

C#多线程学习—生产者和消费者

    下面定义生产者类 CellProd 和消费者类 CellCons ,它们都只有一个方法ThreadRun(),以便在Main()函数中提供给线程的ThreadStart代理对象,作为线程的入口。

 public class CellProd
{
      Cell cell; // 被操作的Cell对象
      int quantity = 1; // 生产者生产次数,初始化为1

      public CellProd(Cell box, int request)
      {
        //构造函数
        cell = box;
        quantity = request;
      }
      public void ThreadRun( )
      {
        for(int looper=1; looper<=quantity; looper++)
            cell.WriteToCell(looper); //生产者向操作对象写入信息
      }
}

public class CellCons
{
      Cell cell;
      int quantity = 1;

      public CellCons(Cell box, int request)
      {
                //构造函数
        cell = box;
        quantity = request;
      }
      public void ThreadRun( )
      {
        int valReturned;
        for(int looper=1; looper<=quantity; looper++)
            valReturned=cell.ReadFromCell( );//消费者从操作对象中读取信息
      }
}

    然后在下面这个类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

    事实上,这个简单的例子已经帮助我们解决了多线程应用程序中可能出现的大问题,只要领悟了解决线程间冲突的基本方法,很容易把它应用到比较复杂的程序中去。


上一页  [1] [2] [3] 

【责编:Ken】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Dotnet频道相关导航