多线程抢票_多线程抢票系统浅析
笔者打算写个轻量版的秒杀系统,那么需要多线程模拟客户去抢购某个商品。故有想先写一个简单的多线程抢票系统加深一下对线程池,同步的理解。
1.新建Java project,命名为ClientApp1, src文件夹里面新建demo文件夹。
项目结构如下,
2.程序模拟的场景用例如下,
多个线程模拟多个客户去购买春运车票
每个客户购买车票【0,9】,最少买0张,最多能买九张。
每个客户同步的买票,当某个线程在买票时,其他线程处于等待状态
所有客户线程买票完毕,主线程最后统计一共卖出多少张车票,切忌不能超卖。
CountDownLatch这个类使主线程等待其他线程各自执行完毕后再执行。
3.代码如下:
packagedemo;importjava.util.Random;importjava.util.concurrent.CountDownLatch;importorg.apache.log4j.Logger;public class Ticket implementsRunnable {private Integer capacity; //一共有多少张票
private Integer soldTickets = 0; //最后总计售出多少张票//CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。//是通过一个计数器来实现的,计数器的初始值是线程的数量。//每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后处于等待的线程就可以恢复工作了。
privateCountDownLatch latch;//使用Log4j2写日志
privateLogger log;public voidsetLog(Logger log) {this.log =log;
}publicTicket(Integer c, CountDownLatch latch) {//TODO Auto-generated constructor stub
this.capacity =c;this.latch =latch;
}publicInteger getSoldTickets() {returnsoldTickets;
}
@Overridepublic synchronized voidrun() {//每个线程客户购买0~9张票
int count = new Random().nextInt(10);
log.info(Thread.currentThread().getName()+ " wants to buy tickets : " +count);if(capacity >=count) {
capacity-=count;
soldTickets+=count;
log.info(Thread.currentThread().getName()+ " has bought tickets successfully. The left tikcets : " +capacity);
}else{
log.info(String.format("Insufficient tickets[%d], stop trading now.", capacity));
}
latch.countDown();
}
}
packagedemo;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.LinkedBlockingQueue;importjava.util.concurrent.ThreadPoolExecutor;importjava.util.concurrent.TimeUnit;importorg.apache.log4j.LogManager;importorg.apache.log4j.Logger;public classTicketPractice {private staticExecutorService pool;private staticCountDownLatch latch;private static Integer NUMBER = 5000; //客户线程数目
private static final Logger logger = LogManager.getLogger(TicketPractice.class);public static voidmain(String[] args) {//TODO Auto-generated method stub
pool = new ThreadPoolExecutor(100, NUMBER, 300, TimeUnit.SECONDS,new LinkedBlockingQueue(NUMBER),Executors.defaultThreadFactory(),newThreadPoolExecutor.AbortPolicy());
latch= newCountDownLatch(NUMBER);
Ticket task= newTicket(NUMBER, latch);
task.setLog(logger);for(int i=0;i
pool.execute(task);
}try{
latch.await();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("+++++++++++++++++++++++++++++++++++");
logger.info("Sold tickets in total : " +task.getSoldTickets());
logger.info("+++++++++++++++++++++++++++++++++++");
}
}
4.值得一提的是,如使用Log4j2,需要引入外部三个jar包
log4j-1.2-api-2.12.1.jar
log4j-api-2.12.1.jar
log4j-core-2.12.1.jar
Log4j2.xml内容如下,
5.运行程序,5000个客户线程随机买票,总票数5000张,不能超卖。程序运行日志如下,
22:11:10.317 INFO demo.Ticket 37 run - pool-2-thread-1 wants to buy tickets : 0
22:11:10.322 INFO demo.Ticket 41 run - pool-2-thread-1 has bought tickets successfully. The left tikcets : 5000
22:11:10.322 INFO demo.Ticket 37 run - pool-2-thread-100 wants to buy tickets : 6
22:11:10.322 INFO demo.Ticket 41 run - pool-2-thread-100 has bought tickets successfully. The left tikcets : 4994
22:11:10.323 INFO demo.Ticket 37 run - pool-2-thread-99 wants to buy tickets : 5
22:11:10.323 INFO demo.Ticket 41 run - pool-2-thread-99 has bought tickets successfully. The left tikcets : 4989
。。。。。。
。。。。。。
22:11:11.359 INFO demo.Ticket 37 run - pool-2-thread-3 wants to buy tickets : 2
22:11:11.359 INFO demo.Ticket 44 run - Insufficient tickets[0], stop trading now.
22:11:11.365 INFO demo.TicketPractice 38 main - +++++++++++++++++++++++++++++++++++
22:11:11.366 INFO demo.TicketPractice 39 main - Sold tickets in total : 5000
22:11:11.366 INFO demo.TicketPractice 40 main - +++++++++++++++++++++++++++++++++++
多线程抢票_多线程抢票系统浅析相关推荐
- 多线程抢票_多线程抢票案例
说明: 利用多线程对网络抢票进行模拟演示. 技术点: (1)实现Runnable接口 (2)重写run方法 (3)创建Thread对象调用start()方法 (4)线程锁 (5)线程休眠 packag ...
- 如何用python抢鞋_谁知道抢鞋机器人的原理是什么吗?
写爬虫老手了. 首先从宏观上将,抢鞋机器人(下称爬虫)就是模拟的人的操作. 从网络层面上讲,人抢鞋和爬虫抢鞋,理论上讲都是发送网络请求.通俗点讲,就是通过网络请求告诉服务器你要干什么. 所以要实现一个 ...
- python模拟app抢号_实验室抢号神器
packageStep1;importjava.util.Calendar;importorg.apache.commons.httpclient.HttpClient;importorg.apach ...
- python多线程下载编程_多线程的 Python 教程——“贪吃蛇”
这是一篇为初学者准备的关于 线程 和Python中的多线程编程的指南. 如果你有一些 类(class)的基础知识 (什么是类,如何定义方法(method),还有方法总是将self作为他的第一个参数,子 ...
- python 多线程 全站小说_多线程下载小说
引言 不知道说啥子, 直接进入正题,哦,本人实测,一本一万多章的小说大概四分钟能爬完,在此想说(小说)网站牛逼,不像学校的教务系统,说多了都是泪 多线程 爬取属于io密集型的,所以引入多线程 redi ...
- mfc多线程编程实例_多线程技术的PLC与PC的通讯方式
点击箭头处"工业之家",选择"关注公众号"! 基于多线程技术的PLC与PC的通讯方式 1.系统构成 推进系统中,PC机选用工控计算机.它是整个控制系统的核心, ...
- java多线程 注意事项_多线程使用及注意事项
1.并行和并发的区别 2.多线程(高并发编程)的优点 3.多线程程序需要注意事项 4.线程的启动与安全中止 5.怎么安全中止线程(interrupt()) 并行和并发的区别: 一个是同时执行,一个是交 ...
- java 多线程不安全_多线程并发为什么不安全
一.线程安全定义 定义: 多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他操作,调用这个对象的行为都可以获得正确的结果 ...
- python拼多多1分抢手机_如何抢到拼多多1元秒杀?抢不到是怎么回事?
在拼多多上面的活动也很多,秒杀活动的种类也不少,比如说1元秒杀.9块9秒杀活动等,那么作为拼多多用户,肯定都想要知道如何抢到拼多多1元秒杀的商品了,下面就来给各位支支招. 1.保证网速畅通 一般网速畅 ...
- java多线程 丢数据_多线程list.add()丢数据
问题: 根据项目业务需求需要统计数据传到前台以图表显示,每天数据量大概20万多,但是每次统计只能统计出10万的数据量,出现数据丢失. 原因: 该接口在之前一次优化时加了多线程,但是数据汇总用的仍是Ar ...
最新文章
- C语言中的scanf()函数介绍
- JAVA实现判断树的子结构及树的镜像问题(《剑指offer》)
- 7月份计划-----dream
- Codeforces 1254C/1255F Point Ordering (交互题)
- c++ array学习
- github基本使用教程
- android power 按键,Android Framework层Power键关机流程(一,Power长按键操作处理)
- docker-machine指定cpu个数
- 基于PyQt的扫雷游戏实现_上篇
- 项目展示-新浪微博客户端
- 梯度下降算法以及线性回归模型
- 写笔记插件_Java程序员笔记(知识)管理的一点经验
- C++primer 16.1.2节练习
- 九宫幻方(蓝桥)深搜
- 谁能教教我, 这个插件是怎么破解 yunfile, yifile, ctfile, 77file 等网盘的
- php 翻译接口,php有道翻译api调用方法
- 全栈学习的知识点梳理(一)
- java程序的结构与类型实验报告_20172301 《Java软件结构与数据结构》实验三报告...
- 【思维】如何放下心中的执念?
- 智能车|直流电机、编码器与驱动器---减速器
热门文章
- miktex报错:the remote package repository is outdated
- Hex Fiend – 十六进制编辑 [Mac]
- Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
- 微生活时光机:去项目中挖掘JS模块化简史
- 一般信道容量迭代算法c语言,(信息论编码)信道容量迭代算法
- linux刷新率设置命令,linux修改屏幕刷新率
- 360°视频论文调研
- 网站分析05——流量分析
- 如何将EAN13码批量输出成PDF
- Delta RPMs disabled because /usr/bin/applydeltarpm not installed.问题解决记录