C#线程同步的三类情景分析

2019-12-26 12:15:36丽君

什么情况下会被认为是情景二?

  当所操作的公共资源存在并发数限制的时候(如数据库连接、IIS连接数限制等),就被认为是情景二。

情景三:我让你动,你才能动!

情景三关注的是线程执行过程中的先后顺序,而用于保证这种先后顺序的方式就是通过线程通信的方式:ManualResetEventSlim、ManualResetEvent、AutoResetEvent。

什么情况下会被认为是情景三?

当两个线程所处理的事情有先后的依赖时,比如线程二的执行过程依赖线程一的执行结果,那就认为是情景三。

不限使用情景

上面的各种方案并不是绝对只限于某一场景,比如 AutoResetEvent 即可以用于情景三,也可以用于情景一。但是,杀鸡焉用牛刀,虽然使用 AutoResetEvent 能够实现情景一的需求,但是用不了 AutoResetEvent 的线程通信能力,同时又会有一些额外的限制(每个线程必须保证 wait 和 set 的成对使用,否则一个线程在锁定资源后就可能被另一个线程解锁)。

 

复制代码     lock (m)
    {
        //....
    }
     
    //等价于如下方式
    autoResetEvent.WaitOne();
    //....
    autoResetEvent.Set();

 


  也有朋友说,可以用情景一中的 lock 方案来实现情景三的需求。


    AutoResetEvent autoReset = new AutoResetEvent(false);
    private void button1_Click(object sender, EventArgs e)
    {      
        Task.Run(() =>
        {
            autoReset.WaitOne();
            Console.WriteLine("步骤二");
        });
 
        Thread.Sleep(1000);//故意延迟从而保证第二个线程是在第一个线程之后才执行
        Task.Run(() =>