设为首页 加入收藏

TOP

C# 针对特定的条件进行锁操作,不用lock,而是mutex(一)
2019-09-17 16:49:51 】 浏览:46
Tags:针对 特定 条件 进行 操作 不用 lock mutex

背景:用户领取优惠券,同一个用户需要加锁验证是否已经领取,不同用户则可以同时领取。

上代码示例:

1、创建Person类

    /// <summary>
    /// Person类
    /// </summary>
    public class Person
    {
        /// <summary>
        /// id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        ///  姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 是否获得优惠券
        /// </summary>
        public bool IsGetCoupon { get; set; }
    }

2.1、不加锁的方法(可能会出现重复领取的情况)

        /// <summary>
        /// 获取优惠券
        /// </summary>
        public static void GetCoupon(Person person)
        {
            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},前来领取优惠券", DateTime.Now, person.Name);
            if (person.IsGetCoupon)
            {
                //假装业务处理
                Thread.Sleep(1000);
                Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},已经领取,不可重复领取", DateTime.Now, person.Name);
            }
            else
            {
                //假装业务处理
                Thread.Sleep(1000);
                //领取
                person.IsGetCoupon = true;
                Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},领取成功", DateTime.Now, person.Name);
            }
        }

2.2、加lock锁的方法,所有来领优惠券的人,都得排对领(也不好)

        /// <summary>
        /// Lock获取优惠券
        /// </summary>
        public static void LockGetCoupon(Person person)
        {
            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},前来领取优惠券", DateTime.Now, person.Name);
            lock (LockObj)
            {
                //判断是否已经领取
                if (person.IsGetCoupon)
                {
                    //假装业务处理
                    Thread.Sleep(1000);
                    Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},已经领取,不可重复领取", DateTime.Now, person.Name);
                }
                else
                {
                    //假装业务处理
                    Thread.Sleep(1000);
                    //领取
                    person.IsGetCoupon = true;
                    Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},领取成功", DateTime.Now, person.Name);
                }
            }
        }

2.3、mutex锁,互斥锁,只有相同id的人,才会排对领取,不同id的人就可以同时领取

        /// <summary>
        /// Mutex,领取
        /// </summary>
        /// <param name="person"></param>
        public static void MutexGetCoupon(Person person)
        {
            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},前来领取优惠券", DateTime.Now, person.Name);
            using (var mutex = new Mutex(false, person.Id.ToString()))
            {
                try
                {
                    if (mutex.WaitOne(-1, false))
                    {
                        //判断是否已经领取
                        if (person.IsGetCoupon)
                        {
                            //假装业务处理
                            Thread.Sleep(1000);
                            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},已经领取,不可重复领取", DateTime.Now, person.Name);
                        }
                        else
                        {

                            //假装业务处理
                            Thread.Sleep(1000);
                            //领取
                            person.IsGetCoupon = true;
                            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},领取成功", DateTime.Now, person.Name);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //TxtLogHelper.WriteLog(ex);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }
    }

3.1、开始测试(不加锁)

        static void Main(string[] args)
        {
            //实例化三个人
            Person p1 = new Person { Id = 24, Name = "Kobe" };
            Person p2 = new Person { Id = 25, Name = "Rose" };
            Person p3 = new Person { Id = 23, Name = "Lebl" };

            //开启多线程、模拟三个人同时发起多次领取请求
            for (int i = 0; i < 4; i++)
            {
                new Thread(() =>
                {
                    GetCoupon(p1);
                }).Start();
                new Thread(() =>
                {
                    GetCoupon(p2);
                }).Start();
                new Thread(() =>
                {
                    GetCoupon(p3);
                }).Start();
            }
            Console.ReadLine();
        }

测试结果:每个人都重复领取

3.2、测试lock锁方法,

        private static readonly object LockObj = new object();
        static void Main(string[] args)
        {
            //实例化三
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇实现通过COM组件方式实现java调用.. 下一篇基于C# 调用百度AI 人脸识别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目