.Net线程足迹(一)

开始学习线程了,做个记录:)

 

1、在这个小例子里,将创建一个新线程,我们将用两个线程演示多线程的工作方式。

 

 

程序的运行结果如下:

MainThread: 0
NewThread: 0
MainThread: 1
NewThread: 1
MainThread: 2
NewThread: 2
MainThread: 3
NewThread: 3
MainThread: 4
NewThread: 4

 

在上面的例子中,Thread.Sleep(n)方法把当前线程置于n毫秒的休眠状态。在主函数中定义了一个新的线程,其中它的起点是函数ThreadStartMethod(),然后包含了Start()方法开始执行。运行例子,就会了解线程间的切换(让CPU从运行一个线程转到另一个线程),也就是让线程几乎同时运行,为了能看哪个线程运行更快我把主线程设置比新线程少100毫秒。

 

2、再看下面这个示例。

怎么让主线程等待呢。可以通过ManualResetEvent 或 AutoResetEvent的WaitOne()方法。

 

 

3、假如我们不想在开始一个新线程后就让它马上运行结束,也就是说,开启了一个新线程后让它运行,然后在某个特定的时间点,新线程暂停并等待从主线程(或其他线程)发来的消息。
这时就可以这样定义:
  public static ManualResetEvent manualEvent = new ManualResetEvent(false);
ManualResetEvent允许线程通过发信号互相通信,构造函数的布尔值可以设置ManualResetEvent 的初始状态,false表示初始状态为非终止状态。
像本例中初始化时直接把false作为start的初始状态,也就是通知另一个线程,让它等待一个或多个线程。
等待线程就要调用:
manualEvent.WaitOne();
所以等待线程就要无限期的阻塞并等待类来通知。

发信号的线程调用Set()方法发送信号。
manualEvent.Set();
这样等待线程就会被通知,值变为true,同时停止等待。

 

运行的结果如下:

Thread: Waiting for a Signal.
MainThread: 0
MainThread: 1
MainThread: 2
Thread: Get a Signal.
MainThread: 3
NewThread:0
MainThread: 4
NewThread:1
Main: Waiting for thread to stop.
NewThread:2
Main: Waiting for thread to stop.
NewThread:3
Main: Waiting for thread to stop.
NewThread:4
Main: Waiting for thread to stop.

 

4、在下面的例子中,学习一下AutoResetEvent的用法。

在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似。从字面意思看,它们都表示是一个事件(Event)。这两个类都有WaitOne方法,这个方法被调用后,当前的线程(即是调用这个方法的线程)暂停运行(可以看做等待事件触发),直到事件被触发(即另外的线程调用了它的Set方法)

ManualResetEvent说明这个事件被触发后(Set方法被调用),是要手工进行重置的(即调用Reset方法),否则再次调用它的WaitOne方法是没有用的(也就是调用WaitOne的线程不会停下等待事件触发,而是继续执行)。 它提供手工重置的方法是调用Reset方法。

AutoResetEvent则是Set被调用后,如果WaitOne再次被调用,当前的线程还是会被暂停的,也就是不用手工调用它的Reset方法,就能使WaitOne再次生效。

 

看下面两个示例:

示例1:

运行结果如下:

ThreadMethod.
ThreadMethod.

示例2:这个示例演示了ManualResetEvent调用过Set方法后,再次调用WaitOne是无效的,必须先调用Reset方法

运行结果如下:

ThreadMethod.
 

另外这两个类的区别还有一点,就在调用后,AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程;而ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。

 

5、上面叙述了AutoResetEvent和ManualResetEvent的主要区别,对于这个区别希望大家不要视而不见。也就是AutoResetEvent一次只唤醒一个线程,而ManualResetEvent则可以唤醒多个线程。再举个小例子详细说明一下。

 

比如你想送花给一个MM,托了一个送花的小伙子送了过去,而你希望当MM收到花之后就立即打个电话过去告诉她。
但问题是你不知道花什么时候才送到MM的手里,打早了打迟了都不好,这时你可以使用ManualResetEvent对象帮忙。当委托小伙子送花过去的时候,使用ManualResetEvent的WaitOne方法进行等待。当小伙子把花送到MM的手中时,再调用一下ManualResetEvent的Set方法,你就可以准时地打电话过去了。另外ManualResetEvent还有一个Reset方法,用来重新阻断调用者执行的,情况就好比你委托了这个小伙子送花给N个MM,而又想准时地给这N个MM打电话的情况一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值