C#多线程系列之线程通知主要涵盖三个部分:Monitor、AutoResetEvent和ManualResetEvent。
Monitor
在C#中,Monitor类是一种基本的同步机制,支持两种操作:Enter()和Exit()。Enter()用于请求获取对象的锁,而Exit()用于释放对象的锁,最终达到线程同步的目的。
Monitor类的典型应用场景是在一个线程内部执行一段临界代码。具体的操作流程是,使用Enter()方法获取对象的锁,执行临界代码,然后使用Exit()方法释放对象的锁。示例代码如下:
class Program
{
static object _locker = new object();
static void Main(string[] args)
{
lock (_locker) // 相当于 Monitor.Enter(_locker)
{
// 执行临界代码
} // 相当于 Monitor.Exit(_locker)
}
}
AutoResetEvent
AutoResetEvent类是一种提供线程互斥的机制。一般情况下,它用于等待一个事件的触发,以执行下一步操作。AutoResetEvent类中最重要的方法是WaitOne(),如果当前的AutoResetEvent对象没有发出信号,WaitOne()方法会使得线程进入阻塞状态,直到有其他线程调用Set()方法发出信号通知该线程继续执行。示例代码如下:
class Program
{
static AutoResetEvent _autoEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread t1 = new Thread(() =>
{
Console.WriteLine("Thread 1 is waiting for signal");
_autoEvent.WaitOne(); // 等待信号
Console.WriteLine("Thread 1 is running");
});
Thread t2 = new Thread(() =>
{
Console.WriteLine("Thread 2 is running");
_autoEvent.Set(); // 发出信号
});
t1.Start();
t2.Start();
}
}
运行上面的代码,你会发现Thread 1在等待信号时处于阻塞状态,而Thread 2在执行完成后发出了信号,Thread 1便进入了运行状态。
ManualResetEvent
ManualResetEvent类也是一种提供线程互斥的机制。和AutoResetEvent类不同的是,ManualResetEvent类触发后能一直处于有信号的状态,直到调用了Reset()方法。
ManualResetEvent类中最重要的方法是WaitOne(),如果当前的ManualResetEvent对象没有发出信号,WaitOne()方法会使得线程进入阻塞状态,直到有其他线程调用Set()方法发出信号通知该线程继续执行。示例代码如下:
class Program
{
static ManualResetEvent _manualEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
Thread t1 = new Thread(() =>
{
Console.WriteLine("Thread 1 is waiting for signal");
_manualEvent.WaitOne(); // 等待信号
Console.WriteLine("Thread 1 is running");
});
Thread t2 = new Thread(() =>
{
Console.WriteLine("Thread 2 is running");
_manualEvent.Set(); // 发出信号
});
t1.Start();
t2.Start();
Thread.Sleep(1000); // 睡眠1000ms
_manualEvent.Reset(); // 重新设置为无信号
}
}
运行上面的代码,你会发现Thread 1在等待信号时处于阻塞状态,而Thread 2在执行完成后发出了信号,Thread 1便进入了运行状态。最后,调用Reset()方法将_manualEvent对象重新设置为无信号状态,从而使Thread 1在继续等待信号。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程系列之线程通知 - Python技术站