做一个网站需要怎么做,网站建设没业务,客户为什么要做网站,做网站需要的东西C#多线程学习(六) 互斥对象 原文链接#xff1a;http://kb.cnblogs.com/page/42533/ 本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者和消费者 C#多线程学习(四) 多线程的自动管理(线程池) C#多线程学习(五) 多… C#多线程学习(六) 互斥对象 原文链接http://kb.cnblogs.com/page/42533/ 本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者和消费者 C#多线程学习(四) 多线程的自动管理(线程池) C#多线程学习(五) 多线程的自动管理(定时器) C#多线程学习(六) 互斥对象 如何控制好多个线程相互之间的联系不产生冲突和重复这需要用到互斥对象即System.Threading 命名空间中的 Mutex 类。 我们可以把Mutex看作一个出租车乘客看作线程。乘客首先等车然后上车最后下车。当一个乘客在车上时其他乘客就只有等他下车以后才可以上车。而线程与Mutex对象的关系也正是如此线程使用Mutex.WaitOne()方法等待Mutex对象被释放如果它等待的Mutex对象被释放了它就自动拥有这个对象直到它调用Mutex.ReleaseMutex()方法释放这个对象而在此期间其他想要获取这个Mutex对象的线程都只有等待。 下面这个例子使用了Mutex对象来同步四个线程主线程等待四个线程的结束而这四个线程的运行又是与两个Mutex对象相关联的。 其中还用到AutoResetEvent类的对象可以把它理解为一个信号灯。这里用它的有信号状态来表示一个线程的结束。 // AutoResetEvent.Set()方法设置它为有信号状态 // AutoResetEvent.Reset()方法设置它为无信号状态 Mutex 类的程序示例 Code
using System;
using System.Threading;
namespace ThreadExample
{
publicclass MutexSample{static Mutex gM1;static Mutex gM2;constint ITERS 100;static AutoResetEvent Event1 new AutoResetEvent(false);static AutoResetEvent Event2 new AutoResetEvent(false);static AutoResetEvent Event3 new AutoResetEvent(false);static AutoResetEvent Event4 new AutoResetEvent(false);publicstaticvoid Main(String[] args){Console.WriteLine(Mutex Sample );
//创建一个Mutex对象并且命名为MyMutexgM1 new Mutex(true,MyMutex);
//创建一个未命名的Mutex 对象.gM2 new Mutex(true);Console.WriteLine( - Main Owns gM1 and gM2);AutoResetEvent[] evs new AutoResetEvent[4];evs[0] Event1; //为后面的线程t1,t2,t3,t4定义AutoResetEvent对象evs[1] Event2; evs[2] Event3; evs[3] Event4; MutexSample tm new MutexSample( );Thread t1 new Thread(new ThreadStart(tm.t1Start));Thread t2 new Thread(new ThreadStart(tm.t2Start));Thread t3 new Thread(new ThreadStart(tm.t3Start));Thread t4 new Thread(new ThreadStart(tm.t4Start));t1.Start( );// 使用Mutex.WaitAll()方法等待一个Mutex数组中的对象全部被释放t2.Start( );// 使用Mutex.WaitOne()方法等待gM1的释放t3.Start( );// 使用Mutex.WaitAny()方法等待一个Mutex数组中任意一个对象被释放t4.Start( );// 使用Mutex.WaitOne()方法等待gM2的释放Thread.Sleep(2000);Console.WriteLine( - Main releases gM1);gM1.ReleaseMutex( ); //线程t2,t3结束条件满足Thread.Sleep(1000);Console.WriteLine( - Main releases gM2);gM2.ReleaseMutex( ); //线程t1,t4结束条件满足
//等待所有四个线程结束WaitHandle.WaitAll(evs); Console.WriteLine( Mutex Sample);Console.ReadLine();}publicvoid t1Start( ){Console.WriteLine(t1Start started, Mutex.WaitAll(Mutex[]));Mutex[] gMs new Mutex[2];gMs[0] gM1;//创建一个Mutex数组作为Mutex.WaitAll()方法的参数gMs[1] gM2;Mutex.WaitAll(gMs);//等待gM1和gM2都被释放Thread.Sleep(2000);Console.WriteLine(t1Start finished, Mutex.WaitAll(Mutex[]) satisfied);Event1.Set( ); //线程结束将Event1设置为有信号状态}publicvoid t2Start( ){Console.WriteLine(t2Start started, gM1.WaitOne( ));gM1.WaitOne( );//等待gM1的释放Console.WriteLine(t2Start finished, gM1.WaitOne( ) satisfied);Event2.Set( );//线程结束将Event2设置为有信号状态}publicvoid t3Start( ){Console.WriteLine(t3Start started, Mutex.WaitAny(Mutex[]));Mutex[] gMs new Mutex[2];gMs[0] gM1;//创建一个Mutex数组作为Mutex.WaitAny()方法的参数gMs[1] gM2;Mutex.WaitAny(gMs);//等待数组中任意一个Mutex对象被释放Console.WriteLine(t3Start finished, Mutex.WaitAny(Mutex[]));Event3.Set( );//线程结束将Event3设置为有信号状态}publicvoid t4Start( ){Console.WriteLine(t4Start started, gM2.WaitOne( ));gM2.WaitOne( );//等待gM2被释放Console.WriteLine(t4Start finished, gM2.WaitOne( ));Event4.Set( );//线程结束将Event4设置为有信号状态}}
} 程序的输出结果 结果
Mutex Sample
- Main Owns gM1 and gM2
t1Start started, Mutex.WaitAll(Mutex[])
t2Start started, gM1.WaitOne( )
t3Start started, Mutex.WaitAny(Mutex[])
t4Start started, gM2.WaitOne( )
- Main releases gM1
t2Start finished, gM1.WaitOne( ) satisfied
t3Start finished, Mutex.WaitAny(Mutex[])
- Main releases gM2
t1Start finished, Mutex.WaitAll(Mutex[]) satisfied
t4Start finished, gM2.WaitOne( )Mutex Sample 从执行结果可以很清楚地看到线程t2,t3的运行是以gM1的释放为条件的而t4在gM2释放后开始执行t1则在gM1和gM2都被释放了之后才执行。Main()函数最后使用WaitHandle等待所有的AutoResetEvent对象的信号这些对象的信号代表相应线程的结束。 posted on 2012-05-06 19:01 Hao_Guo 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/HaoGuo/archive/2012/05/06/Thread6.html