1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package ccb.ticket; import java.io.File; import java.util.ArrayList; /* 功能实现:多线程模拟售票系统 定义一个车票类,车票类拥有票号属性、 车票状态(未售、售出)属性和拥有者(String类型)属性; 在主线程中定义一个票库(ArrayList数组列表)初始化票库并生产200张票; 定义一个乘客类继承自线程类,有一个名字(String类型)属性, 乘客类每隔10毫秒就去票库中查看有没票, 如果有票就抢一张过来 (把车票标为售出状态,并把车票的拥有者标为自己的名字), 每个乘客抢到20张票就停止运行。 在主线程中创建10个乘客类并启动它们(开始抢票), 要求每个乘客抢到的票不连号,不能多抢或少抢。抢完后打印出每个人抢到的票号。 */ public class Main { //票库 static ArrayList<Ticket> mTicketList = new ArrayList<Ticket>(); public static void main(String[] args) { for ( int i = 0 ; i < 200 ; i++) { Ticket t = new Ticket(); t.ticketNum = i + 100 ; mTicketList.add(t); } Passenger[] passengers = new Passenger[ 5 ]; for ( int i = 0 ; i < 5 ; i++) { passengers[i] = new Passenger( "passenger_" + i /*,mTicketList*/ ); passengers[i].start(); } //等待所有乘客结束 for ( int i = 0 ; i < 5 ; i++) { try { passengers[i].join(); } catch (InterruptedException e) { e.printStackTrace(); } } for ( int i = 0 ; i < passengers.length; i++) { System.out.print(passengers[i].name + "抢到的票:" ); int tCnt = 0 ; //抢到的票数 for ( int j = 0 ; j < mTicketList.size(); j++) { Ticket t = mTicketList.get(j); if (t != null && t.owner != null && passengers[i] != null ) { if (t.owner.equals(passengers[i].name)) { tCnt++; System.out.print(t.ticketNum + "," ); } } } System.out.println( "总票数:" + tCnt); } } } |
购票人:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package ccb.ticket; /** * 旅客线程(并发) */ public class Passenger extends Thread { String name; //名字 //ArrayList<Ticket> mTicketList ; int myTickets = 0 ; public Passenger(String name /*,ArrayList<Ticket> ticketList*/ ) { //mTicketList = ticketList; this .name = name; } @Override public void run() { //Main.mTicketList.get(0); while (myTickets < 20 ) { //开始抢票 for ( int i = 0 ; i < Main.mTicketList.size(); i++) { Ticket t = Main.mTicketList.get(i); //取出第i张票 synchronized (t) { //synchronized (监视的竞争对象) if (t.saledState == Ticket.STATE_NOT_SALED) { //把车票标为售出状态 t.saledState = Ticket.STATE_SALED; //把车票的拥有者标为自己的名字 t.owner = this .name; myTickets++; System.out.println(Thread.currentThread().getName() + this .name + " 抢到" + t.ticketNum + "号票" ); break ; } } /* boolean result = checkTicket(t); if(result){ break; }*/ } try { sleep( 20 ); } catch (InterruptedException e) { e.printStackTrace(); } } } /* * synchronized 默认监视的竞争对象 : 为当前类对象,即this */ public synchronized boolean checkTicket(Ticket t) { if (t.saledState == Ticket.STATE_NOT_SALED) { t.saledState = Ticket.STATE_SALED; //把车票标为售出状态 t.owner = this .name; //把车票的拥有者标为自己的名字 myTickets++; System.out.println( this .name + "抢到" + t.ticketNum + "号票" ); return true ; } return false ; } } |
车票:
1 2 3 4 5 6 7 8 9 10 | package ccb.ticket; public class Ticket { public static final boolean STATE_SALED = true ; //售出状态 public static final boolean STATE_NOT_SALED = false ; //未售出状态 public int ticketNum = 0 ; //票号 public boolean saledState = STATE_NOT_SALED; //初始状态: 未售 public String owner = null ; //拥有者 } |
一个很好的示例,受到了很大的启发!原文出处记不起来了,侵删!
分类:
Java
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!