欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#多線程經(jīng)典示例(吃蘋(píng)果)

 更新時(shí)間:2017年01月12日 09:40:55   作者:飛翔的月亮  
本文主要講述了多線程開(kāi)發(fā)中經(jīng)典示例,通過(guò)本示例,可以加深對(duì)多線程的理解。下面跟著小編一起來(lái)看下吧

本文主要講述了多線程開(kāi)發(fā)中經(jīng)典示例,通過(guò)本示例,可以加深對(duì)多線程的理解。

示例概述:

下面用一個(gè)模擬吃蘋(píng)果的實(shí)例,說(shuō)明C#中多線程的實(shí)現(xiàn)方法。要求開(kāi)發(fā)一個(gè)程序?qū)崿F(xiàn)如下情況:一個(gè)家庭有三個(gè)孩子,爸爸媽媽不斷削蘋(píng)果往盤(pán)子里面放,老大、老二、老三不斷從盤(pán)子里面取蘋(píng)果吃。盤(pán)子的大小有限,最多只能放5個(gè)蘋(píng)果,并且爸媽不能同時(shí)往盤(pán)子里面放蘋(píng)果,媽媽具有優(yōu)先權(quán)。三個(gè)孩子取蘋(píng)果時(shí),盤(pán)子不能為空,三人不能同時(shí)取,老三優(yōu)先權(quán)最高,老大最低。老大吃的最快,取的頻率最高,老二次之。

涉及到知識(shí)點(diǎn):

  • 線程Thread 創(chuàng)建并控制線程,設(shè)置其優(yōu)先級(jí)并獲取其狀態(tài)。
  • 鎖 lock 用于實(shí)現(xiàn)多線程同步的最直接辦法就是加鎖,它可以把一段代碼定義為互斥段,在一個(gè)時(shí)刻內(nèi)只允許一個(gè)線程進(jìn)入執(zhí)行,而其他線程必須等待。
  • 事件EventHandler 聲明一個(gè)事件,用于通知界面做改變

設(shè)計(jì)思路:

  • Productor 表示生產(chǎn)者,用于削蘋(píng)果。
  • Consumer 表示消費(fèi)者,用于吃蘋(píng)果。
  • Dish 盤(pán)子,用于裝蘋(píng)果,做為中間類(lèi)
  • EatAppleSmp 的BeginEat()方法,表示開(kāi)始吃蘋(píng)果,啟動(dòng)線程

效果圖如下【爸爸媽媽削蘋(píng)果,孩子吃蘋(píng)果】:

后臺(tái)輸出如下:

Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Erdi取蘋(píng)果吃...
Sandi等待取蘋(píng)果
Mama放1個(gè)蘋(píng)果
Sandi取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Erdi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Sandi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Erdi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba放1個(gè)蘋(píng)果
Sandi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Erdi取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Mama正在等待放入蘋(píng)果
Sandi取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Mama正在等待放入蘋(píng)果
Erdi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Dage取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Mama正在等待放入蘋(píng)果
Dage取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Erdi取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Sandi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Dage取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Mama正在等待放入蘋(píng)果
Erdi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Sandi取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Mama正在等待放入蘋(píng)果
Dage取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Mama正在等待放入蘋(píng)果
Erdi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Dage取蘋(píng)果吃...
Baba放1個(gè)蘋(píng)果
Mama正在等待放入蘋(píng)果
Sandi取蘋(píng)果吃...
Mama放1個(gè)蘋(píng)果
Baba正在等待放入蘋(píng)果
Mama正在等待放入蘋(píng)果
線程 'Mama' (0x1ce0) 已退出,返回值為 0 (0x0)。
線程 'Baba' (0x1888) 已退出,返回值為 0 (0x0)。
Erdi取蘋(píng)果吃...
Dage取蘋(píng)果吃...
Sandi取蘋(píng)果吃...
Dage取蘋(píng)果吃...
Erdi取蘋(píng)果吃...
Dage等待取蘋(píng)果
Sandi等待取蘋(píng)果
Erdi等待取蘋(píng)果
后臺(tái)輸出

Productor 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 /// <summary>
 /// 生產(chǎn)者
 /// </summary>
 public class Productor
 {
  private Dish dish;
  private string name;
  public string Name
  {
   get { return name; }
   set { name = value; }
  }
  public EventHandler PutAction;//聲明一個(gè)事件,當(dāng)放蘋(píng)果時(shí)觸發(fā)該事件
  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);//削蘋(píng)果時(shí)間
     }
     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>
 /// 消費(fèi)者
 /// </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;//聲明一個(gè)事件,當(dāng)放蘋(píng)果時(shí)觸發(fā)該事件
  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)
    {
     //如果取到蘋(píng)果,則調(diào)用事件,并開(kāi)始吃
     if (GetAction != null)
     {
      GetAction(this, null);
     }
     try
     {
      Thread.Sleep(timelong);//吃蘋(píng)果時(shí)間
     }
     catch (ThreadInterruptedException)
     {
     }
    }
    else {
     break;
    }
   }
  }
 }
}

Dish代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DemoSharp.EatApple
{
 /// <summary>
 /// 盤(pán)子,屬于中間類(lèi)
 /// </summary>
 public class Dish
 {
  private int f = 5;//表示盤(pán)子中還可以放幾個(gè)蘋(píng)果,最多只能放5個(gè)蘋(píng)果
  private int EnabledNum;//可放蘋(píng)果總數(shù)
  private int n = 0; //表示已經(jīng)放了多少個(gè)蘋(píng)果
  private object objGet = new object();
  private object objPut = new object();
  /// <summary>
  /// 構(gòu)造函數(shù),初始化Dish對(duì)象
  /// </summary>
  /// <param name="num">表示削夠多少個(gè)蘋(píng)果結(jié)束</param>
  public Dish(int num)
  {
   this.EnabledNum = num;
  }
  /// <summary>
  /// 放蘋(píng)果的方法
  /// </summary>
  /// <param name="name"></param>
  ///<returns>是否放成功</returns>
  public bool Put(string name)
  {
   lock (this)//同步控制放蘋(píng)果
   {
    bool flag = false;

    while (f == 0)//蘋(píng)果已滿(mǎn),線程等待
    {
     try
     {
      System.Console.WriteLine(name + "正在等待放入蘋(píng)果");
      Monitor.Wait(this);
     }
     catch (Exception ex)
     {
      System.Console.WriteLine(name + "等不及了");
     }
    } 
    if (n < EnabledNum)
    {
     f = f - 1;//削完一個(gè)蘋(píng)果放一次
     n = n + 1;
     System.Console.WriteLine(name + "放1個(gè)蘋(píng)果");
     flag = true;
    }
    Monitor.PulseAll(this);
    return flag;
   }
  }
  /// <summary>
  /// 取蘋(píng)果的方法
  /// </summary>
  /// <param name="name"></param>
  public bool Get(string name)
  {
   lock (this)//同步控制取蘋(píng)果
   {
    bool flag = false;
    while (f == 5)
    {
     try
     {
      System.Console.WriteLine(name + "等待取蘋(píng)果");
      Monitor.Wait(this);
     }
     catch (ThreadInterruptedException) { }
    }
    if (n <= EnabledNum)
    {
     f = f + 1;
     System.Console.WriteLine(name + "取蘋(píng)果吃...");
     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;//聲明一個(gè)事件,當(dāng)放蘋(píng)果時(shí)觸發(fā)該事件
  public EventHandler GetAction;//聲明一個(gè)事件,當(dāng)放蘋(píng)果時(shí)觸發(fā)該事件
  /// <summary>
  /// 開(kāi)始吃蘋(píng)果
  /// </summary>
  public void BeginEat()
  {
   Thread th_mother, th_father, th_young, th_middle, th_old;//依次表示媽媽?zhuān)职?,小弟,二弟,大?
   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;//設(shè)置優(yōu)先級(jí)
   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);
   }
  }
 }
}

界面類(lèi)代碼如下:

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>
 /// 頁(yè)面類(lèi)
 /// </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>
  /// 啟動(dòng)線程
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void btnStart_Click(object sender, EventArgs e)
  {
   this.m_EatAppleSmp.BeginEat();
  }
  /// <summary>
  /// 放蘋(píng)果事件
  /// </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>
  /// 吃蘋(píng)果事件
  /// </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中添加對(duì)象
  /// </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);
   }));
   //顯示個(gè)數(shù)
   lbl.Invoke(new Action(() => {
    if (string.IsNullOrEmpty(lbl.Text))
    {
     lbl.Text = "0";
    }
    lbl.Text = (int.Parse(lbl.Text) + 1).ToString();
   }));
  }
 }
}

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

最新評(píng)論