C#多人抢票模拟器

火车票站点、订票、C#多人抢票模拟器【多线程】_ylq1045的专栏-CSDN博客

上次 抢票模拟器 假定高铁只有一个座位,现在设置高铁共有seatCount个座位

整体模拟程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace TrainPathBookingDemo
{class Program{/// <summary>/// 该高铁共有座位总个数/// </summary>static int seatCount = 3;static void Main(string[] args){LinkedList<string> stationList = new LinkedList<string>(new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N" });Console.WriteLine($"链表的首节点为【{stationList.First.Value}】");Console.WriteLine($"链表的尾节点为【{stationList.Last.Value}】");Tuple<string, string> route1 = Tuple.Create("C", "J");Tuple<string, string> route2 = Tuple.Create("E", "M");Console.WriteLine($"路线1【{route1.Item1}-->{route1.Item2}】 与 路线2【{route2.Item1}-->{route2.Item2}】是否相交:【{IntersectWith(stationList, route1, route2)}】");route1 = Tuple.Create("B", "G");route2 = Tuple.Create("G", "L");Console.WriteLine($"路线1【{route1.Item1}-->{route1.Item2}】 与 路线2【{route2.Item1}-->{route2.Item2}】是否相交:【{IntersectWith(stationList, route1, route2)}】");//四元组:第一项为订票人 第二项代表是否订票成功,第三项代表路线【起始站点】,第四项代表路线【终止站点】List<Tuple<string, bool, string, string>> list = new List<Tuple<string, bool, string, string>>();list.Add(Tuple.Create("甲", false, "A", "E"));list.Add(Tuple.Create("乙", false, "B", "H"));list.Add(Tuple.Create("丙", false, "E", "M"));list.Add(Tuple.Create("丁", false, "K", "N"));list.Add(Tuple.Create("戊", false, "C", "L"));list.Add(Tuple.Create("己", false, "A", "N"));list.Add(Tuple.Create("庚", false, "F", "J"));list.Add(Tuple.Create("辛", false, "M", "N"));list.Add(Tuple.Create("壬", false, "A", "F"));list.Add(Tuple.Create("癸", false, "A", "G"));Console.WriteLine($"------------下面模拟【{list.Count}】个人一起抢高铁票,假设本班高铁【链表】共有【{seatCount}】个座位了------------");for (int i = 0; i < list.Count; i++){int index = i;Task.Run(() => {FightTicket(stationList, list, list[index].Item1);});}Console.ReadLine();}/// <summary>/// 加锁/// </summary>static int lockedValue = 0;/// <summary>/// 抢票/// </summary>/// <param name="stationList">链表:高铁站点</param>/// <param name="list">抢票人与路线 集合</param>/// <param name="bookingPerson">当前抢票人</param>static void FightTicket(LinkedList<string> stationList, List<Tuple<string, bool, string, string>> list, string bookingPerson) {//加锁while (Interlocked.Exchange(ref lockedValue, 1) != 0) { }            Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(100, 500));try{int index = list.FindIndex(tuple => tuple.Item1 == bookingPerson);if (index == -1){throw new Exception($"列表中不存在key,抢票人【{bookingPerson}】");}if (list[index].Item2){//已经抢票成功,不能再次订票Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}【{bookingPerson}】-路线【{list[index].Item3}-->{list[index].Item4}】已订票,不能再次订票!");return;}//查找出所有已经抢票成功的List<Tuple<string, bool, string, string>> fightSuccessList = list.FindAll(tuple => tuple.Item2);if (fightSuccessList.Count == 0){//如果没有发现订票成功的,直接订票成功list[index] = Tuple.Create(bookingPerson, true, list[index].Item3, list[index].Item4);Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}【{bookingPerson}】-路线【{list[index].Item3}-->{list[index].Item4}】已抢票成功");return;}//存在已经抢票成功的,则检查所有路线是否存在相交冲突的List<Tuple<string, bool, string, string>> tupleIntersect = fightSuccessList.FindAll(element =>IntersectWith(stationList, Tuple.Create(element.Item3, element.Item4), Tuple.Create(list[index].Item3, list[index].Item4)));if (tupleIntersect == null || tupleIntersect.Count == 0){//如果没有发现路线相交的,订票成功list[index] = Tuple.Create(bookingPerson, true, list[index].Item3, list[index].Item4);Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}【{bookingPerson}】-路线【{list[index].Item3}-->{list[index].Item4}】已抢票成功");}else {//斯内科 2022-03-06 增加余票个数查询逻辑//发现存在路线相交的,则查询订票成功个数 是否大于等于 座位总个数,如果true【无剩余票】,则订票失败if (tupleIntersect.Count >= seatCount){Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}【{bookingPerson}】订票失败,无余票!当前座位数【{seatCount}】,已抢票数【{tupleIntersect.Count}】,路线【{list[index].Item3}-->{list[index].Item4}】");int bookingIndex = 0;tupleIntersect.ForEach(tuple => Console.WriteLine($"    已订票人{++bookingIndex}:【{tuple.Item1}】路线【{tuple.Item3}-->{tuple.Item4}】"));}else {//如果有余票,则订票成功list[index] = Tuple.Create(bookingPerson, true, list[index].Item3, list[index].Item4);Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}【{bookingPerson}】-路线【{list[index].Item3}-->{list[index].Item4}】已抢票成功,当前座位数【{seatCount}】,已抢票数【{tupleIntersect.Count + 1}】");}}}catch (Exception ex){Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}抢票时出现异常【{ex.Message}】,抢票人【{bookingPerson}】");}finally{//解锁Interlocked.Exchange(ref lockedValue, 0);}}/// <summary>/// 指定的两条路线是否相交,元组的第一个元素代表起始站,第二个元素代表终点站/// </summary>/// <param name="stationList"></param>/// <param name="route1">路线1</param>/// <param name="route2">路线2</param>/// <returns></returns>static bool IntersectWith(LinkedList<string> stationList, Tuple<string, string> route1, Tuple<string, string> route2){//元组的第一项代表起点,第二项代表终点LinkedListNode<string> startNode1 = stationList.Find(route1.Item1);LinkedListNode<string> endNode1 = stationList.Find(route1.Item2);LinkedListNode<string> startNode2 = stationList.Find(route2.Item1);LinkedListNode<string> endNode2 = stationList.Find(route2.Item2);if (startNode1 == null || endNode1 == null || startNode2 == null || endNode2 == null) {//如果节点不存在,直接返回NGreturn false;}if (startNode1.Value == startNode2.Value || endNode1.Value == endNode2.Value) {//如果是同一起始节点 或者 同一结束节点return true;}bool existIntersect = false;while (startNode1 != null){startNode1 = startNode1.Next;if (startNode1 != null && startNode1.Value == endNode1.Value) {//循环从开始节点到终止节点 结束break;}if (startNode1 != null && (startNode1.Value == startNode2.Value || startNode1.Value == endNode2.Value)) {//如果第二个起始节点在第一个元组的【From,To】之间 或者 第二个终点节点在第一个元组的【From,To】之间existIntersect = true;break;}}if (existIntersect) {return true;}//查看 第一个起始节点在第二个元组的【From,To】之间 或者 第一个终点节点在第二个元组的【From,To】之间while (startNode2 != null){startNode2 = startNode2.Next;if (startNode2 != null && startNode2.Value == endNode2.Value){//循环从开始节点到终止节点 结束break;}if (startNode2 != null && (startNode2.Value == startNode1.Value || startNode2.Value == endNode1.Value)){//如果第二个起始节点在第一个元组的【From,To】之间 或者 第二个终点节点在第一个元组的【From,To】之间existIntersect = true;break;}}return existIntersect;        }}
}

程序运行如图:

C#多人抢票模拟器,假设高铁有seatCount个座位相关推荐

  1. php抢票程序,PHP 高并发、抢票、秒杀 解决方案

    对于抢票.秒杀这种业务,我说说自己对这种高并发的理解吧,这里提出个人认为比较可行的几个方案: 方案一:使用队列来实现 可以基于例如MemcacheQ等这样的消息队列,具体的实现方案这么表述吧 比 如有 ...

  2. 12306抢票:极限高并发带来的思考

    每到节假日期间,一二线城市返乡.外出游玩的人们几乎都面临着一个问题:抢火车票!虽然现在大多数情况下都能订到票,但是放票瞬间即无票的场景,相信大家都深有体会.尤其是春节期间,大家不仅使用12306,还会 ...

  3. 军犬舆情每日热点:抢票软件被中铁总局限制;中石化2018净利624亿

    1.中国铁路总局:抢票软件已被限制 今日,中国铁路总局介绍,一些第三方软件的相关机器特征已经被识别并被实施限制措施.也就是说,即使用户花钱购买了加速服务,购票的成功率也绝不会像各个抢票软件显示的一样. ...

  4. 高铁订票系统css,高铁订票系统-数据库系统设计.pptx

    高铁订票系统-数据库系统设计 高铁订票系统 一 系统功能 1.用户模块:用于用户注册,用户登录,订票,退票. 2.管理员模块:供后台管理员登录,用于添加,修改车次及票务信息. 3.游客模块:车次相关信 ...

  5. java高铁购票程序代码教学_基于jsp的高铁订票-JavaEE实现高铁订票 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的高铁订票, 该项目可用各类java课程设计大作业中, 高铁订票的系统架构分为前后台两部分, 最终实现在线上进行高铁 ...

  6. 惠及6亿人 投资98亿 沿江高铁武宜段最新进展来了!

    在汉江西岸的钟祥市石牌镇万伏村,机器尖叫着,一台30多米高的塔吊吊起了钢护筒:在对岸,近100米长的铁桥作业平台从田地延伸到江边,作业船清理打桩位置的沉积物. 这是沿江高铁武宜段控制性工程--钟祥汉江 ...

  7. Java作业多线程的应用 三人抢票

    1.三个线程,名称分别为"张三","李四","票贩子",共同抢100张火车票 2.每个线程抢到一张票后,都必须休眠500毫秒,用来模拟网络延 ...

  8. java 12306高并发抢票_PHP 高并发、抢票、秒杀 解决方案

    对于抢票.秒杀这种业务,我说说自己对这种高并发的理解吧,这里提出个人认为比较可行的几个方案: 方案一:使用队列来实现 可以基于例如MemcacheQ等这样的消息队列,具体的实现方案这么表述吧 比如有1 ...

  9. JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票)

    下载 http://download.csdn.net/download/crazyzxljing0621/9969870 前言 10.1要去苏州玩. 9月初去携程买票,发现过几天才放票 现在可以预约 ...

最新文章

  1. Java基础学习总结(9)——this关键字
  2. C++基础:C++类成员属性的一种简洁实现
  3. A股融资融券余额是什么意思?
  4. linux7系统怎么启动ftp,教你如何在CentOS7系统中配置ftp服务
  5. KVM虚拟机内无agent情况下的监控方法
  6. 吴恩达机器学习笔记7-数据绘制
  7. 数据中心进水了怎么办?数据中心如何防洪?
  8. 从今天起开始认认真真的写博客
  9. mybaties总结+hibernate总结
  10. leetcode109. 有序链表转换二叉搜索树(深度优先搜索/快慢指针)
  11. 信息学奥赛一本通 1316:【例4.6】数的计数(Noip2001) | 1914:【01NOIP普及组】数的计数 | 洛谷 P1028 [NOIP2001 普及组] 数的计算
  12. springboot ServletContextListener接口
  13. VMware vSAN 技术详解 | 资料
  14. 勘测定界界址点坐标交换格式的读写
  15. Ubuntu22.04设置静态ip
  16. 摩克机器人_第三章 摩克都市的一场灾难(上)
  17. 【前端三剑客二】CSS手术刀剖析第二篇
  18. 一、C++基础入门之 Windows下C/C++开发环境配置
  19. 最简单判断工作日/节假日API
  20. MySQL可怕的笛卡尔积

热门文章

  1. 成员信息 c语言,C语言工会成员信息管理系统.doc
  2. cisco虚拟服务器,Cisco路由器端口映射(虚拟服务器)
  3. 【微信红包封面福利】接口测试中测试与开发的配合
  4. 【学习笔记】云计算关键技术_虚拟化
  5. xcode7 查看 run script 运行结果
  6. ST-LINK/V2烧录AT32芯片方法
  7. Filebeat日志收集器
  8. html转码问题 htmlEncode
  9. 我是通过自学C语言转做软件开发工作的,后来用C++、JavaScript、Java、Scala、OC等语言,也都是自学。我觉得,自学一门编程语言,遵循下面的步骤比较容易学会:
  10. 上周热点回顾(2.16-2.22)