同步构造总结
使用 System.Threading.Monitor
相关类 | 备注 |
---|---|
System.Threading.WaitHandle | 抽象类(方法 WaitOne) |
- | - |
System.Threading.Mutex | 继承 WaitHandle |
System.Threading.Semaphore | 继承 WaitHandle |
System.Threading.EventWaitHandle | 继承 WaitHandle |
- | - |
System.Threading.AutoResetEvent | 继承 EventWaitHandle【地铁闸机,本质是自动关闭】 |
System.Threading.ManualResetEvent | 继承 EventWaitHandle【门,本质是你不手动关门,那就放任自流】 |
- | - |
System.Threading.SemaphoreSlim | 不继承 Semaphore 和 WaitHandle |
System.Threading.ManualResetEventSlim | 不继承 ManualResetEvent 和 EventWaitHandle |
System.Threading.CountdownEvent | 不继承 EventWaitHandle |
原生用户模式同步构造 | 原生内核模式同步构造(比用户模式构造慢很多) |
---|---|
互锁构造 Interlocked | 事件构造event AutoResetEvent |
自旋锁SpinLock | 信号量构造semaphore |
易变构造volatile | 互斥锁构造mutex |
混合模式同步构造 | 备注 |
---|---|
ManualResetEventSlim | 内核 ManualResetEvent + 用户自旋 |
SemaphoreSlim | 内核 Semaphore + 用户自旋 |
# 内核同步构造,适用单例应用
# 用户模式构造,和内核模式构造,统称为基元模式构造
# 对于混合模式构造,就是在没有线程竞争的时候,使用用户模式构造,在多个线程竞争的时候,使用内核模式构造
(1) 信号量 semaphore slim
(2) 监视器monitor
(3) 读写锁reader writer lock slim
(4) 读写锁扩展 one many lock
(5) 倒计数事件count down event
使用CountdownEvent
这个,就是规定多少个信号,然后通过countDownEvent.Signal();
注册信号,并减少计数
调用countDownEvent.Wait();
阻塞当前线程,直到计数减少为0
(6) 栅栏barrier
使用 AutoResetEvent
System.Threading.AutoResetEvent
private static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread thread = new Thread(SayHi);
thread.Start();
autoResetEvent.Set();
autoResetEvent.Set();
autoResetEvent.Set();
}
static void SayHi()
{
while (true)
{
if (autoResetEvent.WaitOne(3 * 1000)) // 等待信号
{
Console.WriteLine("hi");
Thread.Sleep(2 * 1000);
continue;
}
Console.WriteLine("timeout for wait signal");
}
}
System.Threading.Barrier
适用场景,计数,一堆任务,到达某个点,然后统一继续。
barrier.SignalAndWait()
这个就是规定,我们有多少人集合,你到了,你就发信号并等其他人到,到齐了,就可以执行后续事情了。
System.Threading.CountDownEvent
适用场景,适合倒计数,就像规定多少人集合,你到了,你就等待,裁判就发信号说,总共-10人,还剩9人没准备,最后都准备好了,也就是裁判,发了10个信号,等待的任务就可以继续了。
不自动 reset
cdevent.Signal();
cdevent.Wait();
和 barrier 很明显的区别,倒计数,等待和信号,是分开的。
System.Threading.ManualResetEventSlim
适用场景,不计数,一堆任务等待,只要1个信号,就继续执行。
内核 ManualResetEvent + 用户自旋
协调多任务,不限制参与的任务数量
只要1个信号,多任务继续执行,需要手动重设
形象比喻,就像是一扇门
manualResetEvent.Wait(tokenSource.Token);
manualResetEvent.Set();
System.Threading.AutoResetEvent
适用场景,不计数,自动重设,每1个信号释放1个任务。
System.Threading.SemaphoreSlim
适用场景,这个可以控制每1个信号释放的任务数
内核 Semaphore + 用户自旋
协调多任务,不限制参与的任务数量
每1个信号可控制释放的任务数量
网友评论