ConcurrentLinkedQueue 模拟火车售票过程
火车票类
public class Ticket {
private String NO; // 车票编号
private double price; // 票价
public Ticket(String nO, double price) {
super();
NO = nO;
this.price = price;
}
public String getNO() {
return NO;
}
public void setNO(String nO) {
NO = nO;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
示例
public class TicketTest5 {
private static Queue<Ticket> queue = new ConcurrentLinkedQueue<Ticket>();
private static Map<String, String> log = new HashMap<>();
private static double totalMoney = 0; // 总金额
private static double initTotalMoney = 0; // 初始化10000张票的总金额
private static Object lock = new Object();
/**
* 初始化10000张火车票信息
*/
static {
for (int i=0; i<10000; i++) {
double money = Math.ceil(Math.random() * 100); // 随机金额
initTotalMoney += money; // 统计所有票的总金额
Ticket ticket = new Ticket("NO_"+i, money);
queue.add(ticket);
}
}
/**
* 模拟业务的付款操作
*/
public static void pay(String no, double money) {
try {
Thread.sleep(10);
synchronized (lock) {
totalMoney += money;
log.put(no, "出票日期:" + new Date());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
CountDownLatch latch = new CountDownLatch(1); // 用于最后打印信息
// 启动100个窗口进行出票
for (int i=0; i<100; i++) {
Runnable run = new Runnable() {
@Override
public void run() {
// 每一个窗口出票数量不限,直至将所有的票售完
while (true) {
Ticket ticket = queue.poll();
if (ticket==null) {
latch.countDown(); // 打开门闩
break;
} else {
// 模拟付款
pay(ticket.getNO(), ticket.getPrice());
System.out.println("正在出票" + ticket.getNO());
}
}
}
};
Thread thread = new Thread(run);
thread.start();
}
// 暂停,直至所有的票都售完再执行下面操作
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
// 将结果延时打印出来
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("耗时 :" + (end - start));
System.out.println("10000张票初始总金额:" + initTotalMoney);
System.out.println("售出总金额:" + totalMoney);
System.out.println("合计售出数量 :" + log.size());
}
}
输出结果:

ConcurrentLinkedQueue 模拟火车售票过程的更多相关文章
- Java多线程 编写三各类Ticket、SaleWindow、TicketSaleCenter分别代表票信息、售票窗口、售票中心。 售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程。
package com.swift; import java.util.ArrayList; import java.util.HashMap; import java.util.List; impo ...
- 项目实战:Qt+C#轨道交通行业高性能高流畅度模拟火车移动图像控件
需求 高清线阵相机扫描火车并自动切割单节车厢完成图像合成.通过视频图像处理组件流畅模拟火车行驶整个过程的视频图像: 1.模拟火车通过时的滚动图像,图像主要以两侧和顶部图像的预览为主; 2.模拟 ...
- Telnet 模拟邮件发送过程
Telnet 模拟邮件发送过程 windows要提前开启Telnet客户端的功能,再按照下面步骤完成邮件发送: 1.通过 cmd 进入命令窗口 2.连接要发送邮件的服务器:telnet smtp.al ...
- 编写Java程序,用户在网上购买商品(good),当用户买了一本书(book)、一顶帽子(hat)或者买了一双鞋子(shoe),卖家就会通过物流将商品邮寄给用户,使用简单工厂模式模拟这一过程。
查看本章节 查看作业目录 需求说明: 编写Java程序,用户在网上购买商品(good),当用户买了一本书(book).一顶帽子(hat)或者买了一双鞋子(shoe),卖家就会通过物流将商品邮寄给用户, ...
- 编写Java程序,前方有 3km 的道路障碍,4 辆普通车不能通过,必须等到清障车完成作业离开后,才能继续行驶。用程序来模拟这一过程的发生
查看本章节 查看作业目录 需求说明: 前方有 3km 的道路障碍,4 辆普通车不能通过,必须等到清障车完成作业离开后,才能继续行驶.用程序来模拟这一过程的发生 实现思路: 创建清障车Wrecker类和 ...
- 编写Java程序,模拟五子棋博弈过程中的异常声明和异常抛出
返回本章节 返回作业目录 需求说明: 模拟五子棋博弈过程中的异常声明和异常抛出,判断用户所下棋子的位置,是否超越了棋盘的边界. 棋盘的横坐标的范围为0-9,纵坐标范围为0-14,如果用户所放棋子的坐标 ...
- Mysql模拟故障恢复案例过程
一.数据库全备,全备脚本如下: [root@leader script]# cat bak_all.sh #!/bin/bash#Date: 2019-12-08#Author: chan#Mail: ...
- python模拟websocket握手过程中计算sec-websocket-accept
背景 以前,很多网站使用轮询实现推送技术.轮询是在特定的的时间间隔(比如1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给浏览器.轮询的缺点很明显,浏览器需要不断的向服 ...
- Oracle11gr2_ADG管理之在备库上模拟failover的过程实战
技术建议和方案. 要求failover后不重建备库,并能够把failover的数据库重新切换回备库 主库为newtest,备库为snewtest 备库上已经开启了闪回 得到一个参考的SCN SQL&g ...
随机推荐
- ckeditor5富文本编辑器在vue中的使用
安装依赖: npm install --save @ckeditor/ckeditor5-vue @ckeditor/ckeditor5-build-classic 要创建编辑器实例,必须首先将编辑器 ...
- 1D mesauring
The Basics of Measure Objects 2.1 the process of 1D Edge extraction Then, the mean ...
- LeetCode OJ:Gas Station(加油站问题)
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- 关于python中urllib.urlencode的时候出错:UnicodeEncodeError: ‘ascii’的记录
原文我参见了:http://hi.baidu.com/setcookie/item/ddc6b694b1f13435336eeb3c 为毛我要费事的写下了,就是为了让自己记录一下,下面的也是直接摘录过 ...
- DLL声明导出函数的两种方式
DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport):另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出.属 ...
- Mimiktaz抓取本机密码
Mimiktaz2.0以后的版本只需要两条命令即可实现密码的抓取 mimikatz # privilege::debug mimikatz # sekurlsa::logonpasswords
- 各个数据库中top 的表示方法
Select Top在不同数据库中的使用用法: 1. Oracle数据库 SELECT * FROM TABLE1 WHERE ROWNUM<=N 2. Infomix数据库 SELECT FI ...
- 网络请求工具 cURL
网络请求工具 cURL 2017-08-16 cRUL 是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在“标准输出”(stdout)上面. 查看网页源码 1 $ curl baidu. ...
- TypeError: pivot_table() got an unexpected keyword argument 'rows'
利用Python进行数据分析>第二章,处理MovieLens 1M数据集,有句代码总是报错: mean_rating = data.pivot_table('rating', rows='tit ...
- Shell 关闭指定进程
例如要关闭jupyter-notebook这个进程: - | 说明:管道符“|”用来隔开两个命令,管道符左边命令的输出会作为管道符右边命令的输入. “ps -ef” 查看所有进程 “grep -v g ...