C#队列Queue实现一个简单的电商网站秒杀程序
电商的秒杀和抢购,对程序员来说,都不是一个陌生的东西。然而,从技术的角度来说,这对于Web系统是一个巨大的考验。当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要。
我们直接将请求放入队列Queue中的,采用FIFO(First Input First Output,先进先出),这样的话,我们就不会导致某些请求永远获取不到锁。这里有点强行将多线程变成单线程的感觉。
秒杀看似简单,但是可能会存在两个问题:高并发和超卖
高并发:比较火秒杀活动同时参与秒杀人数都是10w+的,如此之高的秒杀人数对于网站架构从前到后都是一种考验。
超卖:秒杀商品都会有固定的数量,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的一大难题。
此代码简单说明问题,例如有10万个人秒杀10个商品,我们定义队列queueAll 存放并发的10万人,queueCur存放已经抢到的10个人
1 2 3 | private static int cnt =10; private static Queue< string > queueAll = new Queue< string >(); private static Queue< string > queueCur = new Queue< string >(); |
购买代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public RetData Buy( string uid) { queueAll.Enqueue(uid); if (queueAll.Count > cnt){ return new RetData {Code = -1, Msg = "商品抢光了" , Cnt = 0}; } queueCur.Enqueue(uid); return new RetData { Code = 1, Msg = "恭喜已抢到" , Cnt = cnt - queueAll.Count }; } public class RetData { public int Code { get ; set ; } public string Msg { get ; set ; } public int Cnt { get ; set ; } } |
处理订单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static void HandleQueue() { Task.Factory.StartNew(() => { while ( true ) if (queueCur.Count > 0) HandleOrder(); }); } public static void HandleOrder() { while (queueCur.Count != 0) { Console.WriteLine( "处理用户订单中:" + queueCur.Dequeue()); } } |
Parallel模拟10万用户并发请求
1 2 3 4 5 6 7 8 9 10 11 12 13 | var tt = new ThreadPar(); Parallel.For(0, 100000, (t, state) => { var uid = "用户" + t; var x = tt.Buy(uid); if (x.Code == -1) { Console.WriteLine(uid + ":" + x.Msg); //state.Break(); } else Console.WriteLine(uid + ":" + x.Msg + "还剩下:" + x.Cnt + "件" ); }); |
处理中,由于数据太多看不到谁抢到了商品,后面注释了抢不到的输出
用户0、1、75000、50000、50001、50002 、50003 、50004、25000、75001 这10位抢到了商品,其他人都没有抢到,
全部代码示例:

public class ThreadPar { private static int cnt =10; private static Queue<string> queueAll = new Queue<string>(); private static Queue<string> queueCur = new Queue<string>(); //private static object ol = new object(); static ThreadPar() { HandleQueue(); } public RetData Buy(string uid) { queueAll.Enqueue(uid); if (queueAll.Count > cnt){ return new RetData {Code = -1, Msg = "商品抢光了", Cnt = 0}; } queueCur.Enqueue(uid); return new RetData { Code = 1, Msg = "恭喜已抢到", Cnt = cnt - queueAll.Count }; } public class RetData { public int Code { get; set; } public string Msg { get; set; } public int Cnt { get; set; } } public static void HandleQueue() { Task.Factory.StartNew(() => { while (true) if (queueCur.Count > 0) HandleOrder(); }); } public static void HandleOrder() { while (queueCur.Count != 0) { Console.WriteLine("处理用户订单中:" + queueCur.Dequeue()); } } }

class Program { static void Main() { ThreadBuy(); Console.WriteLine("----------操作完成----------"); Console.ReadKey(); } //秒杀 static void ThreadBuy() { System.Threading.Thread.Sleep(10000); var tt = new ThreadPar(); Parallel.For(0, 1000000, (t, state) => { var uid = "用户" + t; var x = tt.Buy(uid); if (x.Code == -1) { Console.WriteLine(uid + ":" + x.Msg); //state.Break(); } else { Console.WriteLine(uid + ":" + x.Msg + "还剩下:" + x.Cnt + "件"); } }); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?