一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C# - C#多線程經(jīng)典示例(吃蘋果)

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

2021-12-18 15:23飛翔的月亮 C#

本文主要講述了多線程開(kāi)發(fā)中經(jīng)典示例,通過(guò)本示例,可以加深對(duì)多線程的理解。下面跟著小編一起來(lái)看下吧

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

示例概述:

下面用一個(gè)模擬吃蘋果的實(shí)例,說(shuō)明C#中多線程的實(shí)現(xiàn)方法。要求開(kāi)發(fā)一個(gè)程序?qū)崿F(xiàn)如下情況:一個(gè)家庭有三個(gè)孩子,爸爸媽媽不斷削蘋果往盤子里面放,老大、老二、老三不斷從盤子里面取蘋果吃。盤子的大小有限,最多只能放5個(gè)蘋果,并且爸媽不能同時(shí)往盤子里面放蘋果,媽媽具有優(yōu)先權(quán)。三個(gè)孩子取蘋果時(shí),盤子不能為空,三人不能同時(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)者,用于削蘋果。
  • Consumer 表示消費(fèi)者,用于吃蘋果。
  • Dish 盤子,用于裝蘋果,做為中間類
  • EatAppleSmp 的BeginEat()方法,表示開(kāi)始吃蘋果,啟動(dòng)線程

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Dage取蘋果吃...
Erdi取蘋果吃...
Sandi等待取蘋果
Mama放1個(gè)蘋果
Sandi取蘋果吃...
Baba放1個(gè)蘋果
Dage取蘋果吃...
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Erdi取蘋果吃...
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Dage取蘋果吃...
Sandi取蘋果吃...
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Erdi取蘋果吃...
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Dage取蘋果吃...
Mama放1個(gè)蘋果
Baba放1個(gè)蘋果
Sandi取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Erdi取蘋果吃...
Baba放1個(gè)蘋果
Dage取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Mama正在等待放入蘋果
Sandi取蘋果吃...
Baba放1個(gè)蘋果
Mama正在等待放入蘋果
Erdi取蘋果吃...
Mama放1個(gè)蘋果
Dage取蘋果吃...
Baba放1個(gè)蘋果
Mama正在等待放入蘋果
Dage取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Erdi取蘋果吃...
Baba放1個(gè)蘋果
Sandi取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Dage取蘋果吃...
Baba放1個(gè)蘋果
Mama正在等待放入蘋果
Erdi取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Sandi取蘋果吃...
Baba放1個(gè)蘋果
Mama正在等待放入蘋果
Dage取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Mama正在等待放入蘋果
Erdi取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Dage取蘋果吃...
Baba放1個(gè)蘋果
Mama正在等待放入蘋果
Sandi取蘋果吃...
Mama放1個(gè)蘋果
Baba正在等待放入蘋果
Mama正在等待放入蘋果
線程 'Mama' (0x1ce0) 已退出,返回值為 0 (0x0)。
線程 'Baba' (0x1888) 已退出,返回值為 0 (0x0)。
Erdi取蘋果吃...
Dage取蘋果吃...
Sandi取蘋果吃...
Dage取蘋果吃...
Erdi取蘋果吃...
Dage等待取蘋果
Sandi等待取蘋果
Erdi等待取蘋果
后臺(tái)輸出

Productor 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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)放蘋果時(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);//削蘋果時(shí)間
     }
     catch (Exception ex)
     {
     }
    }
    else {
     break;
    }
   }
  }
 }
}

Consumer代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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)放蘋果時(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)
    {
     //如果取到蘋果,則調(diào)用事件,并開(kāi)始吃
     if (GetAction != null)
     {
      GetAction(this, null);
     }
     try
     {
      Thread.Sleep(timelong);//吃蘋果時(shí)間
     }
     catch (ThreadInterruptedException)
     {
     }
    }
    else {
     break;
    }
   }
  }
 }
}

Dish代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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;//表示盤子中還可以放幾個(gè)蘋果,最多只能放5個(gè)蘋果
  private int EnabledNum;//可放蘋果總數(shù)
  private int n = 0; //表示已經(jīng)放了多少個(gè)蘋果
  private object objGet = new object();
  private object objPut = new object();
  /// <summary>
  /// 構(gòu)造函數(shù),初始化Dish對(duì)象
  /// </summary>
  /// <param name="num">表示削夠多少個(gè)蘋果結(jié)束</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;//削完一個(gè)蘋果放一次
     n = n + 1;
     System.Console.WriteLine(name + "放1個(gè)蘋果");
     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代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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)放蘋果時(shí)觸發(fā)該事件
  public EventHandler GetAction;//聲明一個(gè)事件,當(dāng)放蘋果時(shí)觸發(fā)該事件
  /// <summary>
  /// 開(kāi)始吃蘋果
  /// </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;//設(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);
   }
  }
 }
}

界面類代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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è)面類
 /// </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>
  /// 放蘋果事件
  /// </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中添加對(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í)也希望多多支持服務(wù)器之家!

原文鏈接:http://www.cnblogs.com/hsiang/p/6267147.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品永久免费视频观看 | 免费草比视频 | 青青在线香蕉国产精品 | 日本zzzzwww大片免费 | 动漫美女被褥吸奶漫画漫画 | 妹妹你插的我好爽 | 久久黄色录像 | 日韩一区二三区无 | 亚洲丁香网 | 天堂久久久久va久久久久 | 91热国产| 日韩欧美a | 超级乱淫伦短篇小说做车 | 91精品国产人成网站 | 丰满肥臀风间由美357在线 | 好大好猛好爽好深视频免费 | 精品福利一区 | 青青青草国产 | 狠狠婷婷综合缴情亚洲 | 国产欧美日韩综合二区三区 | 免费在线观看日韩 | 午夜精品久视频在线观看 | 亚洲网站大全 | 暴露狂婷婷医院暴露tx | 男人与禽交的方法 | 国产福利在线观看第二区 | 好大好硬好长好爽a网站 | 污文啊好棒棒啊好了 | 91久久福利国产成人精品 | 欧美成人在线影院 | 国产成人久久精品区一区二区 | 翁熄性放纵交换01 | a男人的天堂久久a毛片 | 欧美一级特黄刺激大片视频 | 色综合天天综合中文网 | 爱福利视频一区 | 草逼视频免费看 | 国产高清一区二区 | 97伊人久久精品亚洲午夜 | 成人精品第一区二区三区 | 深夜福利在线播放 |