C# 多线程经典示例 吃苹果
发布时间:2020-12-16 01:14:14 所属栏目:百科 来源:网络整理
导读:本文主要讲述了多线程开发中经典示例,通过本示例,可以加深对多线程的理解。 示例概述: 下面用一个模拟吃苹果的实例,说明C#中多线程的实现方法。要求开发一个程序实现如下情况:一个家庭有三个孩子,爸爸妈妈不断削苹果往盘子里面放,老大、老二、老三不
本文主要讲述了多线程开发中经典示例,通过本示例,可以加深对多线程的理解。
示例概述: 下面用一个模拟吃苹果的实例,说明C#中多线程的实现方法。要求开发一个程序实现如下情况:一个家庭有三个孩子,爸爸妈妈不断削苹果往盘子里面放,老大、老二、老三不断从盘子里面取苹果吃。盘子的大小有限,最多只能放5个苹果,并且爸妈不能同时往盘子里面放苹果,妈妈具有优先权。三个孩子取苹果时,盘子不能为空,三人不能同时取,老三优先权最高,老大最低。老大吃的最快,取的频率最高,老二次之。
涉及知识点:
设计思路:
效果图 如下【爸爸妈妈削苹果,孩子吃苹果】:
?
核心算法 后台输出如下:
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)。 线程 Baba0x1888) 已退出,返回值为 )。 Erdi取苹果吃... Dage取苹果吃... Sandi取苹果吃... Dage取苹果吃... Erdi取苹果吃... Dage等待取苹果 Sandi等待取苹果 Erdi等待取苹果 Productor 代码如下: 1 using System; 2 System.Collections.Generic; 3 System.Linq; 4 System.Text; 5 System.Threading; 6 7 namespace DemoSharp.EatApple 8 { 9 /// <summary> 10 /// 生产者 11 </summary> 12 public class Productor 13 { 14 private Dish dish; 15 private string name; 16 17 Name 18 { 19 get { return name; } 20 set { name = value; } 21 } 22 23 public EventHandler PutAction;//声明一个事件,当放苹果时触发该事件 24 25 public Productor( name,Dish dish) 26 27 this.name =28 this.dish = dish; 29 30 void run() 31 32 while (true) 33 { 34 bool flag= dish.Put(name); 35 if (flag) 36 { 37 if (PutAction != null38 { 39 PutAction(this,); 40 } 41 try 42 43 Thread.Sleep(600);削苹果时间 44 45 catch (Exception ex) 46 47 48 49 } 50 else { 51 break; 52 53 } 54 55 } 56 } Consumer代码如下: 消费者 Consumer 15 16 17 18 20 21 22 int timelong; 23 24 public EventHandler GetAction;25 26 public Consumer(string name,Dish dish,1)"> timelong) 27 29 30 this.timelong =32 34 35 36 dish.Get(name); 37 39 如果取到苹果,则调用事件,并开始吃 40 if (GetAction != 41 42 GetAction(43 44 45 46 Thread.Sleep(timelong);吃苹果时间 47 48 (ThreadInterruptedException) 50 51 52 53 56 57 58 } Dish代码如下: 盘子,属于中间类 Dish int f = 5;表示盘子中还可以放几个苹果,最多只能放5个苹果 int EnabledNum;可放苹果总数 17 18 int n = 0; 表示已经放了多少个苹果 19 20 object objGet = new object(); 21 object objPut = 24 25 构造函数,初始化Dish对象 26 27 <param name="num">表示削够多少个苹果结束</param> 28 public Dish( num) this.EnabledNum = num; 32 33 放苹果的方法 34 35 <param name="name"></param> 36 ///<returns>是否放成功</returns> 37 bool Put( name) 39 lock (this)同步控制放苹果 41 bool flag = false42 43 while (f == 0)苹果已满,线程等待 47 System.Console.WriteLine(name + "正在等待放入苹果"48 Monitor.Wait(this50 52 System.Console.WriteLine(name + 等不及了 } 55 if (n < EnabledNum) 57 f = f - 1;削完一个苹果放一次 58 n = n + 159 System.Console.WriteLine(name + 放1个苹果60 flag = 61 62 Monitor.PulseAll(63 flag; 64 65 66 67 68 取苹果的方法 69 70 71 bool Get(72 73 同步控制取苹果 74 75 76 577 78 79 80 System.Console.WriteLine(name + 等待取苹果81 Monitor.Wait(82 83 (ThreadInterruptedException) { } 84 85 if (n <=86 87 f = f + 88 System.Console.WriteLine(name + 取苹果吃...89 flag = 90 91 Monitor.PulseAll(92 93 94 95 96 } 97 } EatAppleSmp代码如下: 9 EatAppleSmp 10 11 12 13 14 15 16 开始吃苹果 17 BeginEat() 19 20 Thread th_mother,th_father,th_young,th_middle,th_old;依次表示妈妈,爸爸,小弟,二弟,大哥 21 Dish dish = new Dish(3022 Productor mother = new Productor(",dish);建立线程 23 mother.PutAction += PutActionMethod; 24 Productor father = ,dish); 25 father.PutAction +=26 Consumer old = new Consumer(Dage120027 old.GetAction += GetActionMethod; 28 Consumer middle = Erdi150029 middle.GetAction +=30 Consumer young = Sandi180031 young.GetAction +=32 th_mother = new Thread(new ThreadStart(mother.run)); 33 th_mother.Name = 34 th_father = ThreadStart(father.run)); 35 th_father.Name = 36 th_old = ThreadStart(old.run)); 37 th_old.Name = 38 th_middle = ThreadStart(middle.run)); 39 th_middle.Name = 40 th_young = ThreadStart(young.run)); 41 th_young.Name = 42 th_mother.Priority = ThreadPriority.Highest;设置优先级 43 th_father.Priority = ThreadPriority.Normal; 44 th_old.Priority = ThreadPriority.Lowest; 45 th_middle.Priority =46 th_young.Priority = ThreadPriority.Highest; th_mother.Start(); th_father.Start(); th_old.Start(); th_middle.Start(); th_young.Start(); 53 54 void GetActionMethod( sender,EventArgs e) 56 58 GetAction(sender,e); 59 60 61 62 void PutActionMethod(63 64 66 PutAction(sender,1)">67 68 69 70 } 界面类代码如下: 1 2 3 System.ComponentModel; 4 System.Data; 5 System.Drawing; 6 7 8 System.Windows.Forms; 9 DemoSharp.EatApple; 10 11 DemoSharp 12 13 14 页面类 15 16 partial EatAppleForm : Form 17 18 private EatAppleSmp m_EatAppleSmp = EatAppleSmp(); 19 20 public EatAppleForm() 21 22 InitializeComponent(); 23 InitView(); 24 m_EatAppleSmp.PutAction += 25 m_EatAppleSmp.GetAction += 26 27 28 29 初始化GroupBox 30 31 InitView() 32 33 .gbBaba.Controls.Clear(); 34 .gbMama.Controls.Clear(); 35 .gbDage.Controls.Clear(); 36 .gbErdi.Controls.Clear(); 37 .gbSandi.Controls.Clear(); 38 39 40 41 启动线程 42 43 <param name="sender"></param> 44 <param name="e"></param> 45 void btnStart_Click( 46 47 .m_EatAppleSmp.BeginEat(); 48 49 50 51 放苹果事件 52 53 54 55 56 57 Productor p = sender as Productor; 58 if (p != 59 60 if (p.Name == 61 62 AddItemToGroupBox(this.gbBaba,1)">.lblBaba); 63 64 65 66 AddItemToGroupBox(this.gbMama,1)">.lblMama); 67 68 69 70 71 72 吃苹果事件 73 74 75 76 77 78 Consumer c = sender Consumer; 79 if (c != 80 81 if (c.Name == 82 83 AddItemToGroupBox(this.gbDage,1)">.lblDage); 84 85 86 87 AddItemToGroupBox(this.gbErdi,1)">.lblErdi); 88 89 90 91 AddItemToGroupBox(this.gbSandi,1)">.lblSandi); 92 93 94 95 96 97 往指定的GroupBox中添加对象 98 99 <param name="gbView"></param> 100 <param name="lbl"></param> 101 AddItemToGroupBox(GroupBox gbView,Label lbl) 102 103 gbView.Invoke(new Action(() => 104 105 PictureBox p = PictureBox(); 106 p.Width = 20107 p.Height = 108 p.Dock = DockStyle.Left; 109 p.Image = this.imgLst01.Images[0]; 110 p.Margin = new Padding(2111 gbView.Controls.Add(p); 112 113 })); 114 显示个数 115 lbl.Invoke(new Action(() =>116 if (.IsNullOrEmpty(lbl.Text)) 117 118 lbl.Text = 0119 120 lbl.Text = (int.Parse(lbl.Text) + ).ToString(); 121 122 123 124 } ? ?源码下载链接,请点击:
?
源码下载 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |