大家好,又见面了,我是你们的朋友全栈君。
ManualResetEvent
ManualResetEvent 用于线程同步,通知一个或多个线程某事件已经发生。通常用于一个线程执行的任务必须在其他线程的任务执行之前完成。
ManualResetEvent状态分为两种:终止状态和非终止状态。当某一任务完成时,将ManualResetEvent设置为终止状态,这样其他等待的线程(一个或多个)将开始执行自己的任务。
注意:一旦它被终止,它将保持终止状态,直到它被手动重置。
代码示例:
代码
class Program
{
static void Main( string [] args)
{
Caclultae calc = new Caclultae();
Console.WriteLine( " Result={0} " ,calc.result( 234 ).ToString());
Console.Read();
}
}
class Caclultae
{
double baseNum,firNum,secNum,thdNum;
AutoResetEvent[] autoEvents;
ManualResetEvent manualEvent;
Random Generator;
public Caclultae()
{
autoEvents = new AutoResetEvent[]
{
new AutoResetEvent( false ),
new AutoResetEvent( false ),
new AutoResetEvent( false )
};
manualEvent = new ManualResetEvent( false );
}
void CalBase( object stateInfo)
{
baseNum = Generator.NextDouble();
Console.WriteLine( " BaseNum is Ok " );
manualEvent.Set();
}
void CalFirst( object stateInfo)
{
double preCalc = Generator.NextDouble();
manualEvent.WaitOne();
Console.WriteLine( " FirstNum begins to Calculate " );
firNum = preCalc * baseNum * Generator.NextDouble();
autoEvents[ 0 ].Set();
Console.WriteLine( " FirstNum Calculates successfully " );
}
void CalSec( object stateInfo)
{
double preCalc = Generator.NextDouble();
manualEvent.WaitOne();
Console.WriteLine( " SecNum begins to Calculate " );
secNum = preCalc * baseNum * Generator.NextDouble();
autoEvents[ 1 ].Set();
Console.WriteLine( " SecNum Calculates successfully " );
}
void CalThird( object stateInfo)
{
double preCalc = Generator.NextDouble();
manualEvent.WaitOne();
Console.WriteLine( " ThrdNum begins to Calculate " );
thdNum = preCalc * baseNum * Generator.NextDouble();
autoEvents[ 2 ].Set();
Console.WriteLine( " ThrdNum Calculates successfully " );
}
public double result( int seed)
{
Generator = new Random(seed);
ThreadPool.QueueUserWorkItem( new WaitCallback(CalBase));
ThreadPool.QueueUserWorkItem( new WaitCallback(CalFirst));
ThreadPool.QueueUserWorkItem( new WaitCallback(CalSec));
ThreadPool.QueueUserWorkItem( new WaitCallback(CalThird));
WaitHandle.WaitAll(autoEvents);
manualEvent.Reset();
return firNum + secNum + thdNum;
}
}
代码中,我们可以看到,CalFirst,CalSec,CalThird都在等待CalBase执行完成。当CalBase计算出BaseNum的结果之后,将ManualResetEvent变量设置为终止状态,通知其他三个任务,可以执行他们自己的任务了。
执行结果:
1).执行一次的结果:
2). 再次执行的结果:
从两次执行结果中看出,CalFirst、CalSec、CalThird的执行顺序是不一定的,也就是说 这三个的地位是相同的,都在等待CalBase执行成功,从而执行自己的任务。这也验证了 ManualResetEvent的作用,用于通知一个或多个线程某个事件发生。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/161182.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...