.NET多线程

.NET多线程(七)同步构造

2017-03-12  本文已影响0人  万州大牛

同步构造总结

使用 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个信号可控制释放的任务数量

上一篇下一篇

猜你喜欢

热点阅读