LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

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

admin
2023年7月17日 9:32 本文热度 301

本文主要讲述了多线程开发中经典示例,通过本示例,可以加深对多线程的理解。

示例概述:

  下面用一个模拟吃苹果的实例,说明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();            }));        }    }}




该文章在 2023/7/17 9:32:24 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved