IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> C#多人抢票模拟器,假设高铁有seatCount个座位 -> 正文阅读

[Java知识库]C#多人抢票模拟器,假设高铁有seatCount个座位

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) 
            {
                //如果节点不存在,直接返回NG
                return 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;        
        }
    }
}

程序运行如图:

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:14:58  更:2022-03-08 22:19:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:01:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码