Java并发-多线程售票案例
创始人
2024-02-24 03:20:31
0

1. 前言

本节内容主要是使用 Java 的使用 Condition 和 Lock 机制对多线程售票案例进行实现。售票案例多数情况下主要关注多线程如何安全的减少库存,也就是剩余的票数,当票数为 0 时,停止减少库存。

2. 售票机制模型

如下图所示,有两个售票窗口进行售票,有一个窗口处理退票,这既是现实生活中一个简单的售票机制。

场景设计

  • 创建一个工厂类 TicketCenter,该类包含两个方法,saleRollback 退票方法和 sale 售票方法;
  • 定义一个车票总数等于 10 ,为了方便观察结果,设置为 10。学习者也可自行选择数量;
  • 对于 saleRollback 方法,当发生退票时,通知售票窗口继续售卖车票;
  • 对 saleRollback 进行特别设置,每隔 5000 毫秒退回一张车票;
  • 对于 sale 方法,只要有车票就进行售卖。为了更便于观察结果,每卖出一张车票,sleep 2000 毫秒;
  • 创建一个测试类,main 函数中创建 2 个售票窗口和 1 个退票窗口,运行程序进行结果观察。
  • 修改 saleRollback 退票时间,每隔 25 秒退回一张车票;
  • 再次运行程序并观察结果。
public class DemoTest {public static void main(String[] args) {TicketCenter ticketCenter = new TicketCenter();new Thread(new saleRollback(ticketCenter),"退票窗口"). start();new Thread(new Consumer(ticketCenter),"1号售票窗口"). start();new Thread(new Consumer(ticketCenter),"2号售票窗口"). start();}
}class TicketCenter {private int capacity = 10; // 根据需求:定义10涨车票private Lock lock = new ReentrantLock(false);private Condition saleLock = lock.newCondition();// 根据需求:saleRollback 方法创建,为退票使用public void saleRollback() {try {lock.lock();capacity++;System.out.println("线程("+Thread.currentThread().getName() + ")发生退票。" + "当前剩余票数"+capacity+"个");saleLock.signalAll(); //发生退票,通知售票窗口进行售票} finally {lock.unlock();}}// 根据需求:sale 方法创建public void sale() {try {lock.lock();while (capacity==0) { //没有票的情况下,停止售票try {System.out.println("警告:线程("+Thread.currentThread().getName() + ")准备售票,但当前没有剩余车票");saleLock.await(); //剩余票数为 0 ,无法售卖,进入 wait} catch (InterruptedException e) {e.printStackTrace();}}capacity-- ; //如果有票,则售卖 -1System.out.println("线程("+Thread.currentThread().getName() + ")售出一张票。" + "当前剩余票数"+capacity+"个");} finally {lock.unlock();}}
}class saleRollback implements Runnable {private TicketCenter TicketCenter; //关联工厂类,调用 saleRollback 方法public saleRollback(TicketCenter TicketCenter) {this.TicketCenter = TicketCenter;}public void run() {while (true) {try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}TicketCenter.saleRollback(); //根据需求 ,调用 TicketCenter 的 saleRollback 方法}}
}
class Consumer implements Runnable {private TicketCenter TicketCenter;public Consumer(TicketCenter TicketCenter) {this.TicketCenter = TicketCenter;}public void run() {while (true) {TicketCenter.sale(); //调用sale 方法try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

总结:售票机制与生产者 - 消费者模式存在着细微的区别,需要学习者通过代码的实现慢慢体会。由于售票方法只需要进入 await 状态,退票方法需要唤醒售票的 await 状态,因此只需要创建一个售票窗口的 Condition 对象

相关内容

热门资讯

【追踪】河南方城县一民办小学1... 界面新闻记者 | 张旭 界面新闻编辑 | 刘海川 历经两次延期开庭,2025年12月19日上午,...
多件法律案将提请全国人大常委会... 12月19日,全国人大常委会法制工作委员会举行发言人记者会介绍,十四届全国人大常委会第十九次会议将于...
汇源再发声明:已提起诉讼,要求... 北京汇源食品饮料有限公司(以下简称“北京汇源”)重整一案,受到社会各界的广泛关注。重整方案实施以来,...
俄外交部发言人:日方不负责任的... 俄罗斯外交部发言人扎哈罗娃18日表示,俄方始终关注日方加速重新军国主义化的危险性,其国防开支急剧增长...
支持家庭适老化改造 政策再加力 央视网消息:近日,多部门联合出台《关于增强消费品供需适配性进一步促进消费的实施方案》,明确提出:“优...
德龙汇能[000593]关于子... 本版导读 2025-12-20 2025-12-20 2025-12-20 2025...
政策优势显著,发展机遇更多,国... 【环球时报记者 郭媛丹 环球时报驻俄罗斯特派记者 肖新新 环球时报驻法国特约记者 董铭】12月18日...
锚定制度型开放 勇当内陆开放新... “市委十二届九次全会紧扣党中央‘稳步扩大制度型开放’的战略部署,为‘十五五’开放发展擘画了宏伟蓝图,...
世贸组织报告指出——国际贸易政... 日前,世贸组织发布《世贸组织贸易政策审查——国际贸易环境发展概览》,指出全球贸易政策环境在2024年...