C#多线程经典示例(吃苹果)

2019-12-30 15:50:33王旭

Productor 代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 /// <summary>
 /// 生产者
 /// </summary>
 public class Productor
 {
  private Dish dish;
  private string name;
  public string Name
  {
   get { return name; }
   set { name = value; }
  }
  public EventHandler PutAction;//声明一个事件,当放苹果时触发该事件
  public Productor(string name, Dish dish)
  {
   this.name = name;
   this.dish = dish;
  }
  public void run()
  {
   while (true)
   {
    bool flag= dish.Put(name);
    if (flag)
    {
     if (PutAction != null)
     {
      PutAction(this, null);
     }
     try
     {
      Thread.Sleep(600);//削苹果时间
     }
     catch (Exception ex)
     {
     }
    }
    else {
     break;
    }
   }
  }
 }
}

Consumer代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 /// <summary>
 /// 消费者
 /// </summary>
 public class Consumer
 {
  private string name;
  public string Name
  {
   get { return name; }
   set { name = value; }
  }
  private Dish dish;
  private int timelong;
  public EventHandler GetAction;//声明一个事件,当放苹果时触发该事件
  public Consumer(string name, Dish dish, int timelong)
  {
   this.name = name;
   this.dish = dish;
   this.timelong = timelong;
  }
  public void run()
  {
   while (true)
   {
    bool flag= dish.Get(name);
    if (flag)
    {
     //如果取到苹果,则调用事件,并开始吃
     if (GetAction != null)
     {
      GetAction(this, null);
     }
     try
     {
      Thread.Sleep(timelong);//吃苹果时间
     }
     catch (ThreadInterruptedException)
     {
     }
    }
    else {
     break;
    }
   }
  }
 }
}

Dish代码如下:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 /// <summary>
 /// 盘子,属于中间类
 /// </summary>
 public class Dish
 {
  private int f = 5;//表示盘子中还可以放几个苹果,最多只能放5个苹果
  private int EnabledNum;//可放苹果总数
  private int n = 0; //表示已经放了多少个苹果
  private object objGet = new object();
  private object objPut = new object();
  /// <summary>
  /// 构造函数,初始化Dish对象
  /// </summary>
  /// <param name="num">表示削够多少个苹果结束</param>
  public Dish(int num)
  {
   this.EnabledNum = num;
  }
  /// <summary>
  /// 放苹果的方法
  /// </summary>
  /// <param name="name"></param>
  ///<returns>是否放成功</returns>
  public bool Put(string name)
  {
   lock (this)//同步控制放苹果
   {
    bool flag = false;

    while (f == 0)//苹果已满,线程等待
    {
     try
     {
      System.Console.WriteLine(name + "正在等待放入苹果");
      Monitor.Wait(this);
     }
     catch (Exception ex)
     {
      System.Console.WriteLine(name + "等不及了");
     }
    } 
    if (n < EnabledNum)
    {
     f = f - 1;//削完一个苹果放一次
     n = n + 1;
     System.Console.WriteLine(name + "放1个苹果");
     flag = true;
    }
    Monitor.PulseAll(this);
    return flag;
   }
  }
  /// <summary>
  /// 取苹果的方法
  /// </summary>
  /// <param name="name"></param>
  public bool Get(string name)
  {
   lock (this)//同步控制取苹果
   {
    bool flag = false;
    while (f == 5)
    {
     try
     {
      System.Console.WriteLine(name + "等待取苹果");
      Monitor.Wait(this);
     }
     catch (ThreadInterruptedException) { }
    }
    if (n <= EnabledNum)
    {
     f = f + 1;
     System.Console.WriteLine(name + "取苹果吃...");
     flag = true;
    }
    Monitor.PulseAll(this);
    return flag;
   }
  }
 } 
}