还是老题目,新建两个线程,同时执行,并向ListBox中添加顺序的数字,而这次不同的是,我们要求A线程在对ListBox工作时,不允许其他线程参与,直到A线程执行完之后,其他线程才可以进入并工作。
当然,如果按照上面的要求,我们依然可以用AutoResetEvent来完成这项工作,但是如果我们加上一点小小的要求呢?当B线程亦或者C线程是我们未知的线程,我们无法判断他们何时会启动并参与其中的工作时,AutoResetEvent就已经无法帮助我们完成任务了。
在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在完全满足前一个请求之前,将无法处理每个新请求。 然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。 lock 关键字 lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
逻辑分析:
在我们无法得知其他线程何时会执行AddNumber()方法时,我们应该怎么做?
我们的主要过程中,一个是线程,一个是执行的方法。
想一想之后,我得到了两条思路:
1.在线程上打主意,能否在线程A执行时阻塞其他一切线程?
2.在执行的方法上打主意,能否使线程A在执行时,拒绝其他线程的参与?
分析以上两点,发现对于未知的线程,我暂时想不出有什么办法可以做到...
那么只要把重点放到第二点思路上,怎样才能把这个方法给锁上呢? 是的,锁!
在我们现实生活中,在我们不希望其他人触碰的事务上,都会加上一把锁。那么线程中的锁如何实现呢?
经过一番搜索,我们找到了上面的这一段文字,Lock关键字。
实现方法如下:
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8 //
9 using System.Threading;
10
11 namespace Thread_Lock
12 {
13 public partial class Form2 : Form
14 {
15 public Form2()
16 {
17 InitializeComponent();
18 }
19
20 /* 线程锁
21 * 创建两个线程,同时执行,并向List中添加数字
22 * 要求线程A执行过程中不允许其他线程的参与操作,当A线程执行完之后,List才允许其他线程参与工作
23 * 注:这里的线程B是未知线程
24 **/
25
26 int count = 100; //添加数量
27
28 Thread thread_A;
29 Thread thread_B;
30
31 private void btnStart_Click(object sender, EventArgs e)
32 {
33 thread_A = new Thread(new ThreadStart(AddNumber));
34 thread_B = new Thread(new ThreadStart(AddNumber));
35
36 thread_A.IsBackground = true;
37 thread_B.IsBackground = true;
38
39 //启动线程A和线程B
40 thread_A.Start();
41 thread_B.Start();
42 }
43
44 private void AddNumber()
45 {
46 //锁住ListBox控件,在此方法被执行完毕之后,会自动解锁,其他线程才可以参与工作。
47 lock (this.lstNumber)
48 {
49 for (int i = 0; i < count; i++)
50 {
51 this.lstNumber.Items.Add(i);
52 }
53 }
54 }
55 }
56 }
57
仅仅加了一行代码,就会发现,在其中一支线程执行时,该方法体或者说ListBox被锁定了,其他线程只能在外面等待。
浙公网安备 33010602011771号