【转】.NET多线程编程(11)—— 互斥对象
如何控制好多个线程相互的间联系不产生冲突和重复这需要用到互斥对象即:.Threading 命名空间中Mutex 类
我们可以把Mutex看作个出租车乘客看作线程乘客首先等车然后上车最后下车当个乘客在车上时其他乘客就只有等他下车以后才可以上车而线程和Mutex对象关系也正是如此线程使用Mutex.WaitOne思路方法等待
Mutex对象被释放如果它等待Mutex对象被释放了它就自动拥有这个对象直到它Mutex.ReleaseMutex思路方法释放这个对象而在此期间其他想要获取这个Mutex对象线程都只有等待
下面这个例子使用了Mutex对象来同步 4个线程主线程等待 4个线程结束而这 4个线程运行又是和两个Mutex对象相关联
其中还用到AutoReEvent类对象可以把它理解为个信号灯这里用它有信号状态来表示个线程结束
// AutoReEvent.Set思路方法设置它为有信号状态
// AutoReEvent.Re思路方法设置它为无信号状态
Mutex 类举例:
using;
using.Threading;
ThreadExample
{
publicMutexSample
{
MutexgM1;
MutexgM2;
constITERS=100;
AutoReEventEvent1=AutoReEvent(false);
AutoReEventEvent2=AutoReEvent(false);
AutoReEventEvent3=AutoReEvent(false);
AutoReEventEvent4=AutoReEvent(false);
publicvoidMain(Stringargs)
{
Console.WriteLine("MutexSample…");
//创建个Mutex对象并且命名为MyMutex
gM1=Mutex(true,"MyMutex");
//创建个未命名Mutex对象.
gM2=Mutex(true);
Console.WriteLine("-MainOwnsgM1andgM2");
AutoReEventevs=AutoReEvent[4];
evs[0]=Event1;//为后面线程t1,t2,t3,t4定义AutoReEvent对象
evs[1]=Event2;
evs[2]=Event3;
evs[3]=Event4;
MutexSampletm=MutexSample;
Threadt1=Thread(ThreadStart(tm.t1Start));
Threadt2=Thread(ThreadStart(tm.t2Start));
Threadt3=Thread(ThreadStart(tm.t3Start));
Threadt4=Thread(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("-MainreleasesgM1");
gM1.ReleaseMutex;//线程t2,t3结束条件满足
Thread.Sleep(1000);
Console.WriteLine("-MainreleasesgM2");
gM2.ReleaseMutex;//线程t1,t4结束条件满足
//等待所有 4个线程结束
WaitHandle.WaitAll(evs);
Console.WriteLine("…MutexSample");
Console.ReadLine;
}
publicvoidt1Start
{
Console.WriteLine("t1Startstarted,Mutex.WaitAll(Mutex)");
MutexgMs=Mutex[2];
gMs[0]=gM1;//创建个Mutex作为Mutex.WaitAll思路方法参数
gMs[1]=gM2;
Mutex.WaitAll(gMs);//等待gM1和gM2都被释放
Thread.Sleep(2000);
Console.WriteLine("t1Startfinished,Mutex.WaitAll(Mutex)satisfied");
Event1.Set;//线程结束将Event1设置为有信号状态
}
publicvoidt2Start
{
Console.WriteLine("t2Startstarted,gM1.WaitOne");
gM1.WaitOne;//等待gM1释放
Console.WriteLine("t2Startfinished,gM1.WaitOnesatisfied");
Event2.Set;//线程结束将Event2设置为有信号状态
}
publicvoidt3Start
{
Console.WriteLine("t3Startstarted,Mutex.WaitAny(Mutex)");
MutexgMs=Mutex[2];
gMs[0]=gM1;//创建个Mutex作为Mutex.WaitAny思路方法参数
gMs[1]=gM2;
Mutex.WaitAny(gMs);//等待中任意个Mutex对象被释放
Console.WriteLine("t3Startfinished,Mutex.WaitAny(Mutex)");
Event3.Set;//线程结束将Event3设置为有信号状态
}
publicvoidt4Start
{
Console.WriteLine("t4Startstarted,gM2.WaitOne");
gM2.WaitOne;//等待gM2被释放
Console.WriteLine("t4Startfinished,gM2.WaitOne");
Event4.Set;//线程结束将Event4设置为有信号状态
}
}
}
输出结果:
MutexSample…
-MainOwnsgM1andgM2
t1Startstarted,Mutex.WaitAll(Mutex)
t2Startstarted,gM1.WaitOne
t3Startstarted,Mutex.WaitAny(Mutex)
t4Startstarted,gM2.WaitOne
-MainreleasesgM1
t2Startfinished,gM1.WaitOnesatisfied
t3Startfinished,Mutex.WaitAny(Mutex)
-MainreleasesgM2
t1Startfinished,Mutex.WaitAll(Mutex)satisfied
t4Startfinished,gM2.WaitOne
…MutexSample
从执行结果可以很清楚地看到线程t2,t3运行是以gM1释放为条件而t4在gM2释放后开始执行t1则在gM1和gM2都被释放了的后才执行Main最后使用WaitHandle等待所有AutoReEvent对象信号这些对象信号代表相应线程结束。
This posting is provided "AS IS" with no warranties, and confers no rights.
浙公网安备 33010602011771号