C# 多线程与队列操作小练刀
之前写Web没有应用到多线程与队列的知识,写了个小程序,练了一把手,模拟商品抢购,代码如下:
class Program { public static Random r = new Random(); public static int GoodsStock = 30; public static Queue payq = new Queue(); public static Queue waitq = new Queue(); static void Main(string[] args) { //增加监视线程 ThreadStart childref3 = new ThreadStart(LookAtActiveThread); Console.WriteLine("监视线程启动了!"); Thread childThread3 = new Thread(childref3); childThread3.Start(); //增加用户抢购线程 ThreadStart childref1 = new ThreadStart(UserBuyInsertThread); Console.WriteLine("用户群1开始抢购了!"); Thread childThread1 = new Thread(childref1); childThread1.Start(); //增加用户抢购线程 ThreadStart childref4 = new ThreadStart(UserBuyInsertThread); Console.WriteLine("用户群2开始抢购了!"); Thread childThread4 = new Thread(childref4); childThread4.Start(); //增加开始结账线程 ThreadStart childref2 = new ThreadStart(UserPayEndThread); Console.WriteLine("结账线程启动了!"); Thread childThread2 = new Thread(childref2); childThread2.Start(); Console.ReadKey(); } //监视线程,抢购结束后关闭所有线程 public static void LookAtActiveThread() { DateTime TempDT = new DateTime(); int totalCount = GoodsStock; while (true) { if (GoodsStock == 0 && payq.Count == 0 && waitq.Count == 0) { TimeSpan ts = DateTime.Now.Subtract(TempDT); Console.WriteLine("抢购活动已结束," + totalCount + "个商品已在" + ts.Seconds + "秒售罄 当前时间:" + DateTime.Now); break; } else { Thread.Sleep(100); } } } //购买用户随机排队插入队列 排队总人数不能超过10个 public static void UserBuyInsertThread() { try { while (true) { if (GoodsStock > 0) { //判断等待队列是否为空,付款队列是否已满,直接加入到付款队列中 if (waitq.Count==0 && payq.Count < GoodsStock) { int userid = r.Next(10000, 99999); payq.Enqueue(userid); Console.WriteLine("用户" + userid + "下单成功,请尽快付款 当前付款队列:" + payq.Count + " 当前时间:" + DateTime.Now); Thread.Sleep(r.Next(100)); } else { int userid = r.Next(10000, 99999); waitq.Enqueue(userid); Console.WriteLine("用户" + userid + "已加入到等待队列中 当前等待队列:" + waitq.Count + " 当前时间:" + DateTime.Now); Thread.Sleep(r.Next(500, 2000)); } } else { Console.WriteLine("对不起,您来晚了,商品已售罄"); Thread.Sleep(300); } if (GoodsStock == 0 && payq.Count == 0 && waitq.Count == 0) { //停止线程 Console.WriteLine("排队线程结束 当前时间:" + DateTime.Now); break; } } } catch (ThreadAbortException e) { Console.WriteLine("用户排队线程出错了:" + e.ToString()); } } //用户购买操作,付款时间比较随机 public static void UserPayEndThread() { try { while (true) { if (payq.Count == 0 && waitq.Count == 0) { Thread.Sleep(300); } else { if (GoodsStock == 0) { if (waitq.Count > 0) { int userid = (int)waitq.Dequeue(); Console.WriteLine("对不起" + userid + ",商品已被抢购一空! 下次请努力! 当前时间:" + DateTime.Now); Thread.Sleep(100); } } else { if (payq.Count > 0) { int userid = (int)payq.Dequeue(); //用户一定概率的超时或者取消订单 if (r.Next(1, 10) < 3) { Console.WriteLine("对不起,用户" + userid + "已超时或取消订单! 当前付款队列:" + payq.Count + " 当前时间:" + DateTime.Now + " 当前库存:" + GoodsStock); } else { GoodsStock -= 1; Console.WriteLine("恭喜!用户" + userid + "已结账,购买成功! 当前付款队列:" + payq.Count + " 当前时间:" + DateTime.Now + " 当前库存:" + GoodsStock); } //把等待队列中的用户加入到付款队列中,判断付款队列中是否超过库存数量s if (GoodsStock > 0 && GoodsStock > payq.Count && waitq.Count > 0) { userid = (int)waitq.Dequeue(); payq.Enqueue(userid); Console.WriteLine("用户" + userid + "已从排队队列加入到付款队列,请尽快付款!当前付款队列:" + payq.Count + " 当前时间:" + DateTime.Now + " 当前库存:" + GoodsStock); } Thread.Sleep(r.Next(100, 500)); } } } if (GoodsStock == 0 && payq.Count == 0 && waitq.Count == 0) { //停止线程 Console.WriteLine("付款线程结束 当前时间:" + DateTime.Now); break; } } } catch (ThreadAbortException e) { Console.WriteLine("用户结账线程出错了:" + e.ToString()); } } }