您当前的位置: 首页 >  c#

喜欢猪猪

暂无认证

  • 1浏览

    0关注

    228博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C#语言,使用Queue类进行秒杀抢票的使用,防止超卖以及顺序进行购票(先到先得)

喜欢猪猪 发布时间:2019-06-04 19:28:05 ,浏览量:1

电商的秒杀和抢购,对程序员来说,都不是一个陌生的东西。然而,从技术的角度来说,这对于Web系统是一个巨大的考验。当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要。

我们直接将请求放入队列Queue中的,采用FIFO(FirstInput First Output,先进先出),这样的话,我们就不会导致某些请求永远获取不到锁。这里有点强行将多线程变成单线程的感觉。

秒杀看似简单,但是可能会存在两个问题:高并发和超卖

高并发:比较火秒杀活动同时参与秒杀人数都是10w+的,如此之高的秒杀人数对于网站架构从前到后都是一种考验。

超卖:秒杀商品都会有固定的数量,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的一大难题。

 

特别提醒,在处理的过程中多线程异步处理的时候,Queue不是线程安全的,这个时候需要在关键逻辑是lock锁的进行处理,避免并发的超卖问题;

 

执行函数main

 

            var queueTrain = new QueueTestModule().InitQueue();    //抢到票的队列

            var queueAll = new QueueTestModule().InitQueue();    //所有进入队列的用户队列

            var tt = new QueueTestModule();

            //一个并行线程进行执行抢票操作

            Parallel.For(0, 150, (t, state) =>

            {

                Thread.Sleep(100);

                Train train = new Train();

                train.Name = "用户" + t;

                var x = tt.Buy(queueAll, queueTrain, train);

                if (x.Code == -1)

                {

                    Console.WriteLine(x.Name + ":" + x.Msg);

                    //state.Break();

                }

                else

                    Console.WriteLine(x.Name + ":" + x.Msg + "还剩下:" + x.Cnt + "件");

            });

            //可以进行消化队列

            while (queueTrain.Count != 0)

            {

                Console.WriteLine("当前队列剩余个数:" + queueTrain.Count);

                queueTrain.Dequeue();

                //Console.WriteLine("处理用户订单中:" + queueTrain.Dequeue());

            }

            Console.ReadKey();

 

//封装一个抢票方法

 public class BuyTrainService 

    {

        public static int cnt = 100;

        public Queue InitQueue()

        {

            var tt = new Queue();

            return tt;

        }

        object obj = new object();

        public RetData Buy(Queue AllQueue, Queue tainQueue, Train tain)

        {

            try

            {

                AllQueue.Enqueue(tain);

                if (AllQueue.Count > cnt)

                {

                    return new RetData { Name = tain.Name, Code = -1, Msg = "商品抢光了", Cnt = 0 };

                }

                tainQueue.Enqueue(tain);

                return new RetData { Name = tain.Name, Code = 1, Msg = "恭喜已抢到", Cnt = cnt - tainQueue.Count };

            }

            catch (Exception ex)

            {

                Console.WriteLine("异常:" + ex);

                return new RetData { Name = tain.Name, Code = 1, Msg = "异常:" + ex, Cnt = cnt - tainQueue.Count };

            }

        }

        public class RetData

        {

            public string Name { get; set; }

            public int Code { get; set; }

            public string Msg { get; set; }

            public int Cnt { get; set; }

        }

        public class Train

        {

            public string Name { get; set; }

        }

    }

关注
打赏
1648795721
查看更多评论
立即登录/注册

微信扫码登录

0.0400s