程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#多線程經典示例(吃蘋果)

C#多線程經典示例(吃蘋果)

編輯:C#入門知識

C#多線程經典示例(吃蘋果)。本站提示廣大學習愛好者:(C#多線程經典示例(吃蘋果))文章只能為提供參考,不一定能成為您想要的結果。以下是C#多線程經典示例(吃蘋果)正文


本文次要講述了多線程開發中經典示例,經過本示例,可以加深對多線程的了解。

示例概述:

上面用一個模仿吃蘋果的實例,闡明C#中多線程的完成辦法。要求開發一個順序完成如下狀況:一個家庭有三個孩子,爸爸媽媽不時削蘋果往盤子外面放,老大、老二、老三不時從盤子外面取蘋果吃。盤子的大小無限,最多只能放5個蘋果,並且爸媽不能同時往盤子外面放蘋果,媽媽具有優先權。三個孩子取蘋果時,盤子不能為空,三人不能同時取,老三優先權最高,老大最低。老大吃的最快,取的頻率最高,老二次之。

觸及到知識點:

線程Thread 創立並控制線程,設置其優先級並獲取其形態。 鎖 lock 用於完成多線程同步的最直接方法就是加鎖,它可以把一段代碼定義為互斥段,在一個時辰內只允許一個線程進入執行,而其他線程必需等候。 事情EventHandler 聲明一個事情,用於告訴界面做改動

設計思緒:

Productor 表示消費者,用於削蘋果。 Consumer 表示消費者,用於吃蘋果。 Dish 盤子,用於裝蘋果,做為兩頭類 EatAppleSmp 的BeginEat()辦法,表示開端吃蘋果,啟動線程

效果圖如下【爸爸媽媽削蘋果,孩子吃蘋果】:

後台輸入如下:

Mama放1個蘋果
Baba放1個蘋果
Dage取蘋果吃...
Erdi取蘋果吃...
Sandi等候取蘋果
Mama放1個蘋果
Sandi取蘋果吃...
Baba放1個蘋果
Dage取蘋果吃...
Mama放1個蘋果
Baba放1個蘋果
Erdi取蘋果吃...
Mama放1個蘋果
Baba放1個蘋果
Dage取蘋果吃...
Sandi取蘋果吃...
Mama放1個蘋果
Baba放1個蘋果
Erdi取蘋果吃...
Mama放1個蘋果
Baba放1個蘋果
Dage取蘋果吃...
Mama放1個蘋果
Baba放1個蘋果
Sandi取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Erdi取蘋果吃...
Baba放1個蘋果
Dage取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Mama正在等候放入蘋果
Sandi取蘋果吃...
Baba放1個蘋果
Mama正在等候放入蘋果
Erdi取蘋果吃...
Mama放1個蘋果
Dage取蘋果吃...
Baba放1個蘋果
Mama正在等候放入蘋果
Dage取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Erdi取蘋果吃...
Baba放1個蘋果
Sandi取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Dage取蘋果吃...
Baba放1個蘋果
Mama正在等候放入蘋果
Erdi取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Sandi取蘋果吃...
Baba放1個蘋果
Mama正在等候放入蘋果
Dage取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Mama正在等候放入蘋果
Erdi取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Dage取蘋果吃...
Baba放1個蘋果
Mama正在等候放入蘋果
Sandi取蘋果吃...
Mama放1個蘋果
Baba正在等候放入蘋果
Mama正在等候放入蘋果
線程 'Mama' (0x1ce0) 已加入,前往值為 0 (0x0)。
線程 'Baba' (0x1888) 已加入,前往值為 0 (0x0)。
Erdi取蘋果吃...
Dage取蘋果吃...
Sandi取蘋果吃...
Dage取蘋果吃...
Erdi取蘋果吃...
Dage等候取蘋果
Sandi等候取蘋果
Erdi等候取蘋果
後台輸入

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;
   }
  }
 } 
}

EatAppleSmp代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 public class EatAppleSmp
 {
  public EventHandler PutAction;//聲明一個事情,當放蘋果時觸發該事情
  public EventHandler GetAction;//聲明一個事情,當放蘋果時觸發該事情
  /// <summary>
  /// 開端吃蘋果
  /// </summary>
  public void BeginEat()
  {
   Thread th_mother, th_father, th_young, th_middle, th_old;//順次表示媽媽,爸爸,小弟,二弟,大哥
   Dish dish = new Dish(30);
   Productor mother = new Productor("Mama", dish);//樹立線程
   mother.PutAction += PutActionMethod;
   Productor father = new Productor("Baba", dish);
   father.PutAction += PutActionMethod;
   Consumer old = new Consumer("Dage", dish, 1200);
   old.GetAction += GetActionMethod;
   Consumer middle = new Consumer("Erdi", dish, 1500);
   middle.GetAction += GetActionMethod;
   Consumer young = new Consumer("Sandi", dish, 1800);
   young.GetAction += GetActionMethod;
   th_mother = new Thread(new ThreadStart(mother.run));
   th_mother.Name = "Mama";
   th_father = new Thread(new ThreadStart(father.run));
   th_father.Name = "Baba";
   th_old = new Thread(new ThreadStart(old.run));
   th_old.Name = "Dage";
   th_middle = new Thread(new ThreadStart(middle.run));
   th_middle.Name = "Erdi";
   th_young = new Thread(new ThreadStart(young.run));
   th_young.Name = "Sandi";
   th_mother.Priority = ThreadPriority.Highest;//設置優先級
   th_father.Priority = ThreadPriority.Normal;
   th_old.Priority = ThreadPriority.Lowest;
   th_middle.Priority = ThreadPriority.Normal;
   th_young.Priority = ThreadPriority.Highest;
   th_mother.Start();
   th_father.Start();
   th_old.Start();
   th_middle.Start();
   th_young.Start();
  }
  private void GetActionMethod(object sender,EventArgs e)
  {
   if (GetAction != null)
   {
    GetAction(sender, e);
   }
  }
  private void PutActionMethod(object sender, EventArgs e)
  {
   if (PutAction != null)
   {
    PutAction(sender, e);
   }
  }
 }
}

界面類代碼如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DemoSharp.EatApple;
namespace DemoSharp
{
 /// <summary>
 /// 頁面類
 /// </summary>
 public partial class EatAppleForm : Form
 {
  private EatAppleSmp m_EatAppleSmp = new EatAppleSmp();
  public EatAppleForm()
  {
   InitializeComponent();
   InitView();
   m_EatAppleSmp.PutAction += PutActionMethod;
   m_EatAppleSmp.GetAction += GetActionMethod;
  }
  /// <summary>
  /// 初始化GroupBox
  /// </summary>
  private void InitView()
  {
   this.gbBaba.Controls.Clear();
   this.gbMama.Controls.Clear();
   this.gbDage.Controls.Clear();
   this.gbErdi.Controls.Clear();
   this.gbSandi.Controls.Clear();
  }
  /// <summary>
  /// 啟動線程
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void btnStart_Click(object sender, EventArgs e)
  {
   this.m_EatAppleSmp.BeginEat();
  }
  /// <summary>
  /// 放蘋果事情
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void PutActionMethod(object sender, EventArgs e)
  {
   Productor p = sender as Productor;
   if (p != null)
   {
    if (p.Name == "Baba")
    {
     AddItemToGroupBox(this.gbBaba, this.lblBaba);
    }
    if (p.Name == "Mama")
    {
     AddItemToGroupBox(this.gbMama, this.lblMama);
    }
   }
  }
  /// <summary>
  /// 吃蘋果事情
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  public void GetActionMethod(object sender, EventArgs e)
  {
   Consumer c = sender as Consumer;
   if (c != null)
   {
    if (c.Name == "Dage")
    {
     AddItemToGroupBox(this.gbDage, this.lblDage);
    }
    if (c.Name == "Erdi")
    {
     AddItemToGroupBox(this.gbErdi, this.lblErdi);
    }
    if (c.Name == "Sandi")
    {
     AddItemToGroupBox(this.gbSandi, this.lblSandi);
    }
   }
  }
  /// <summary>
  /// 往指定的GroupBox中添加對象
  /// </summary>
  /// <param name="gbView"></param>
  /// <param name="lbl"></param>
  private void AddItemToGroupBox(GroupBox gbView,Label lbl)
  {
   gbView.Invoke(new Action(() =>
   {
    PictureBox p = new PictureBox();
    p.Width = 20;
    p.Height = 20;
    p.Dock = DockStyle.Left;
    p.Image = this.imgLst01.Images[0];
    p.Margin = new Padding(2);
    gbView.Controls.Add(p);
   }));
   //顯示個數
   lbl.Invoke(new Action(() => {
    if (string.IsNullOrEmpty(lbl.Text))
    {
     lbl.Text = "0";
    }
    lbl.Text = (int.Parse(lbl.Text) + 1).ToString();
   }));
  }
 }
}

以上就是本文的全部內容,希望本文的內容對大家的學習或許任務能帶來一定的協助,同時也希望多多支持!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved