首页 > 编程语言 > 详细

线程同步之事件

时间:2016-07-08 00:06:08      阅读:303      评论:0      收藏:0      [点我收藏+]

  我们可以使用lock、Mutex来保证共享资源被正确的操作,但当多个线程之间需要相互通信时,如线程A完成之后要告诉线程B,B在接着做,

这时我们应该怎么处理,那就要用到线程的事件。.Net中提供了AutoResetEvent和ManualResetEvent两个类来处理。

  当线程需要独占资源时,使用AutoResetEvent.WaitOne()来等待资源,如果AutoResetEvent为非终止状态,则线程阻塞,等待其它线程释放资源。其它线程

使用完资源,通过调用Set方法来释放资源,通知等待线程资源可用。第一个等待的线程接到信号之后即可占用资源继续执行,当线程执行完毕,会自动将AutoResetEvent设置

为终止状态。

AutoResetEvent 在初始化时通过参数来设置初始化状态,true表示终止状态,false表示非终止状态。

我们来看一个例子。

分两个人完成植树,A负责挖树坑,B负责搬树苗及浇水。代码实现如下:

 

public class ThreadEventTest
    {
        private static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
        public static void PlantTree()
        {
            //挖坑
            Thread shovelThread = new Thread(new ThreadStart(Shovel));
            shovelThread.Name = "A";
            shovelThread.Start();
            Thread.Sleep(100);
            //种树浇水
            Thread warterThread = new Thread(new ThreadStart(WarterTree));
            warterThread.Name = "B";
            warterThread.Start();            
        }

        private static void Shovel()
        {            
            Console.WriteLine("线程{0}开始挖坑",Thread.CurrentThread.Name);            
            Console.WriteLine("线程{0}挖坑完成,可以种树浇水了", Thread.CurrentThread.Name);
            autoResetEvent.Set();
        }

        private static void WarterTree()
        {            
            Console.WriteLine("线程{0}开始搬运树苗并准备水", Thread.CurrentThread.Name);                        
            Console.WriteLine("线程{0}已将树苗和水准备就绪,等待挖坑完成后可以种树浇水了", Thread.CurrentThread.Name);
            autoResetEvent.WaitOne();

            Console.WriteLine("线程{0}开始种树浇水", Thread.CurrentThread.Name);
            Thread.Sleep(1000);
            Console.WriteLine("线程{0}种树浇水完成", Thread.CurrentThread.Name);
            //
            Console.WriteLine("完成植树");
        }
    }

主线程开启两个线程A、B分别完成挖坑和浇水。A线程不受限制开启后会执行挖坑任务,此时B线程也会同步执行,但当B线程执行值WaitOne时,由于我们初始化的AutoResetEvent状态为非终止状态,因此B线程必须等待Set信号,只有当A线程执行完毕并进行Set时,即A线程挖坑完成,B线程才能进行植树浇水,从而保证了整个

植树工作有序的完成。

AutoResetEvent在Set之后状态变为终止状态,当WaitOne执行之后又会自动将状态重置为非终止状态,而无需调用Reset(),这就是和ManualResetEvent之间的区别。

ManualResetEvent在Set之后必须要Reset才能重置状态,调用需要成对出现,才能保证WaitOne阻塞线程,使得线程有序的执行下去。

线程同步之事件

原文:http://www.cnblogs.com/oneheart/p/5636359.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!