C# 多线程经典示例 吃苹果
示例概述:
涉及知识点:
- 线程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) 已退出,返回值为 (0x0)。
线程 'Baba' (0x1888) 已退出,返回值为 (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();//削苹果时间
}
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个苹果 private int EnabledNum;//可放苹果总数 private int n = ; //表示已经放了多少个苹果 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 == )//苹果已满,线程等待
{
try
{
System.Console.WriteLine(name + "正在等待放入苹果");
Monitor.Wait(this);
}
catch (Exception ex)
{
System.Console.WriteLine(name + "等不及了");
}
}
if (n < EnabledNum)
{
f = f - ;//削完一个苹果放一次
n = n + ;
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 == )
{
try
{
System.Console.WriteLine(name + "等待取苹果");
Monitor.Wait(this);
}
catch (ThreadInterruptedException) { }
}
if (n <= EnabledNum)
{
f = f + ;
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();
Productor mother = new Productor("Mama", dish);//建立线程
mother.PutAction += PutActionMethod;
Productor father = new Productor("Baba", dish);
father.PutAction += PutActionMethod;
Consumer old = new Consumer("Dage", dish, );
old.GetAction += GetActionMethod;
Consumer middle = new Consumer("Erdi", dish, );
middle.GetAction += GetActionMethod;
Consumer young = new Consumer("Sandi", dish, );
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 = ;
p.Height = ;
p.Dock = DockStyle.Left;
p.Image = this.imgLst01.Images[];
p.Margin = new Padding();
gbView.Controls.Add(p); }));
//显示个数
lbl.Invoke(new Action(() => {
if (string.IsNullOrEmpty(lbl.Text))
{
lbl.Text = "";
}
lbl.Text = (int.Parse(lbl.Text) + ).ToString();
}));
}
}
}
C# 多线程经典示例 吃苹果的更多相关文章
- 【Java】经典示例代码
成鹏致远 | lcw.cnblogs.com | 2014-02-08 单例设计模式 class Singleton{ private static Singleton instance = new ...
- P1676陶陶吃苹果 - vijos
描述 curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果, ...
- ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例
ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例 2012年04月27日 16:59:16 奋斗的小壁虎 阅读数:4500 ...
- [Vijos 1676] 陶陶吃苹果
Description curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上 ...
- 多线程(threading)示例
一.多线程简单示例 import threading,time print('第一线程(默认):程序开始啦!') def takeANap(): time.sleep(5) print('第二线程:5 ...
- C语言位运算、移位运算 经典示例
概述: C语言的位级运算可以运用到任何“整数”的数据类型上,如char.short.int.long.long long.或者unsigned这样的限定词.基本的位运算有与.或.非.异或等等. C语言 ...
- Swift - 跳跃吃苹果游戏开发(SpriteKit游戏开发)
下面通过一个样例演示如何实现飞行道具的生成,以及道具碰撞拾取. 样例说明: 1,屏幕从右到左不断地生成苹果飞过来(苹果高度随机) 2,点击屏幕可以让熊猫跳跃 3,熊猫碰到苹果,苹果消失 运行效果: 样 ...
- JAVA多线程经典问题 -- 生产者 消费者
工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...
- C# TCP多线程服务器示例
前言 之前一直很少接触多线程这块.这次项目中刚好用到了网络编程TCP这块,做一个服务端,需要使用到多线程,所以记录下过程.希望可以帮到自己的同时能给别人带来一点点收获- 关于TCP的介绍就不多讲,神马 ...
随机推荐
- 异步编程中使用帮助类来实现Thread.Start()的示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- JDK5-枚举
1. 使用普通类模拟枚举 public class Weekday { private Weekday() {} // 私有化 public static final Weekday MONDAY = ...
- ie兼容CSS3渐变写法
在css3之前要想做背景色渐变就只能采用添加背景图片的方法,但是随着css3:linear-gradient属性的出现,就可以避免使用添加背景图片的方法,从而优化了性能.但是inear-gradien ...
- 安卓扫码:简单的ZXing使用记录
ZXing是Google提供的条形码.二维码等的生成.解析的库.最近工作需求去研究了一下,主要是研究怎么扫描二维码(QRCode).网上教程也不少,但大多看了不明所以,甚至看了半天都不知道解码到底从哪 ...
- group by、order by 先后顺序问题
今天遇到个小问题 本来是很基础的问题 应该说 基础知道掌握的不牢 好了不说 错误 语句 : select a.a1 from table a where order by a.a1 gro ...
- 移动端web开发调试
手机上安装chrome, 连接上usb允许调试,打开电脑的chrome,输入chrome://inspect 点击电脑页面的inspect即可,这时操作手机和电脑能达到同步显示. android4.4 ...
- Cocos2dx 3.2 节点之间相互通信与设置触摸吞噬的方法
实际开发中,我们经常会遇到这样的情况.我们有一个层layer1,这个层包含一个menu层,menu1层里又包含了一个节点按钮button1.现在需要实现一个效果:点击button1弹出一个对话框,这个 ...
- 原生JS 选项卡代码实现
可实现同页面多个选项卡 效果图: 代码实现: HTML部分 <div class="main" id="tabs"> <div class=& ...
- 个人Python常用Package及其安装
为了避免每次重装系统时又要东翻西找,现在此记录一下目前常用的Python包安装过程. 1) Python: 2.7.11, 下载地址:www.python.org.由于个人喜欢使用PyQt4(其实是不 ...
- 关于手机"内存"的解答
关于手机"内存"的解答 内存小/少 手机内存在手机出厂的时候就已经固定了,其总量无法调整,不能像电脑一样加内存条.所以想提升可用内存,除了经常清理系统,或者把不是必须的应用移到SD ...