zoukankan      html  css  js  c++  java
  • .net core WebApi Mutex实现并发同步

    Mutex,中文译为互斥体,在.net中也是作为一种线程或进程之间的互斥体存在。即在同一时刻,一个共享资源只允许被某一个线程或进程访问,其他线程或进程需要等待(直至获取互斥锁为止)。

    Mutex的使用方式与Monitor很相似,但绝不相同。Monitor支持线程间并发同步,Mutex不但支持线程也支持进程间并发同步。

    Mutex有许多需要注意的地方,如果稍不注意,则你会被坑惨!

    接下来我们使用控制台和webapi项目各自做测试。

    一、使用控制台测试进程间的同步

    测试代码如下:

            [STAThread]
            static void Main(string[] args)
            {
                //使用指定名称为MName的互斥体
                //如果获取到名称为MName的互斥体,则flag为true,否则为false。flag作用很大,如果是指定了互斥体的名称,一定要用flag去判断是否互斥。
                Mutex mutex = new Mutex(true, "MName", out bool flag);
    
                if (flag) {
                    Console.WriteLine("1.获取互斥锁,开始运行");
                    Thread.Sleep(5000);
                    Console.WriteLine("2.释放互斥锁!");
                    mutex.ReleaseMutex();
                    Console.WriteLine("3.开始等待,5秒后超时!");
                    if (mutex.WaitOne(5000))
                        Console.WriteLine("6.获取互斥锁,开始运行!");
                    else Console.WriteLine("6.超时释放互斥锁!");
                    Thread.Sleep(1000);               
                }
                else {
                    Console.WriteLine("1.未获取互斥锁,开始等待!");
                    mutex.WaitOne();
                    Console.WriteLine("4.获取互斥锁,开始运行!");
                    Console.WriteLine("5.释放互斥锁!");
                    mutex.ReleaseMutex();               
                }
    
                 Console.ReadKey();
            }

    同时打开两个程序的运行结果如下所示:

    进程间的并发同步需要指定互斥体的名称,只要是同一个名称,它们就能互斥。

    Mutex的WaitOne()方法是阻塞当前线程并等待获取互斥体。ReleaseMutex()方法是释放当前线程拥有的互斥体,如果当前进程或线程没有拥有互斥体Mutex,则会抛出System.ApplicationException异常,这点需要注意。

    WaitOne和ReleaseMutex方法最好成对出现,反正单个方法两两不相见。

    多个ReleaseMutex方法一起运行的异常见以下图片:

    这个问题可以看ReleaseMutex方法的定义说明:

        /// <summary>Releases the <see cref="T:System.Threading.Mutex"></see> once.</summary>
        /// <exception cref="T:System.ApplicationException">The calling thread does not own the mutex.</exception>
        /// <exception cref="T:System.ObjectDisposedException">The current instance has already been disposed.</exception>
        public void ReleaseMutex();

    产生System.ApplicationException异常的原因就是当前被调用的线程已经不拥有该互斥体!

      

    二、使用WebApi项目测试线程间的同步

     测试代码如下:

            [HttpGet("[controller]/v1/api/[action]")]
            public IActionResult Test() {            
                return Json(SynchronizationTest());
            }
    
            //指定一个互斥体名称
            protected static string MutexName => "MName";
            public ResponseModel SynchronizationTest() {
                ResponseModel rc = new ResponseModel(0, "初始化");
                
                Mutex mutex = new Mutex(true, MutexName, out bool flag);
                try {
                    //如果没有获取到互斥体,则等待,3秒后超时。如果获取到了互斥体,则flag=true,否则flag=false。一定要做flag判断,否则会抛出异常
                    if(!flag)
                        mutex.WaitOne(3000);
    
                    int count = RedisHelper.Get(GoodsNumberKey).ToInt32();
                    if (count > 0) {
                        RedisHelper.Set(GoodsNumberKey, "-1");
                        rc.SetMessage("重置成功!");
                    }
                    else rc.SetMessage("已被重置,本次重置无效");
                    
                    rc.SetCode(Thread.CurrentThread.ManagedThreadId);
                }
                catch (Exception ex) {
                    _log.Error(ex);
                }
                finally {
                    mutex.ReleaseMutex();
                    mutex.Close();
                    mutex.Dispose();
                }
    
                return rc;
            }

    接下来,我们使用如下代码连续发送8次请求

                HttpHelper.GetOnStringAsync($"{Url}/Shop/v1/api/Test", contentType: "application/json").ContinueWith(it =>
                {
                    Console.WriteLine(it.Result);
                });

    测试的结果如下图所示:

    可以看见,我们连续发送8次请求,只有一次重置成功,其他的都因为互斥的关系而重置无效。

  • 相关阅读:
    制作自适应布局的模块及框架(转载)
    从今天起开始写博了
    工作中碰到的css问题解决方法
    标题写个什么好呢
    快速编写HTML(Zen conding)
    2013年1月21日记事
    opc 方面研究
    关于 部署方面研究 Visual Studio 2013
    intel AVX指令集
    关于 返回数据类型 后 加& 的作用
  • 原文地址:https://www.cnblogs.com/williamwsj/p/9719529.html
Copyright © 2011-2022 走看看