用Java的延时队列,实现顾客到了点就自动下机。
所谓延时队列,就是不到固定要求,不能从里面取值,即便取值,取值也为null。
对比其他队列:
SynchronousQueue 队列不能存放数据,存放数据就报错,但是可以先开一个线程持续从其中取值,另一个线程放数据
LinkedBlockingQueue 阻塞有界队列,如果不指定大小,可存放多个值
ArrayBlockingQueue 阻塞无界队列,必须指定大小,超过添加就报错
ConcurrentLinkedQueue 高性能无阻塞无界队列
PriorityBlockingQueue 优先级队列,存放值时不排序,取值时开始排序
DelayQueue 延时无界队列,只有到了设定的条件下才能取值
package cn.base;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* @Description : 需要放入延时队列的对象,需要实现Delayed接口
* @Author : 小书包
* @CreateDate :2018-11-23 18:03
*/
public class Person implements Delayed{
// 用户名
private String name;
// 身份证号
private int id;
// 上机金额
private int money;
// 结束时间
private long endTime;
// 配置当前计算的时间单位,毫秒
private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
public Person(String name, int id, int money) {
this.name = name;
this.id = id;
this.endTime = money * 1000 + System.currentTimeMillis();
}
/**
* 结束时间与当前时间进行比较,返回结果
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
return endTime - System.currentTimeMillis();
}
/**
* 判断是否可以取出
* @param o
* @return
*/
@Override
public int compareTo(Delayed o) {
Person person = (Person) o;
return (int) (this.getDelay(this.timeUnit) - person.getDelay(this.timeUnit));
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
package cn.base;
import java.util.concurrent.DelayQueue;
/**
* @Description : 需要实现Runnable接口
* @Author : 小书包
* @CreateDate :2018-11-23 18:09
*/
public class NetBar implements Runnable {
// 是否正常营业
private volatile boolean isRun = true;
// 延时队列
private DelayQueue<Person> queue = new DelayQueue<>();
/**
* 顾客上机
* @param person
*/
void surfNet(Person person){
System.out.println("顾客:"+person.getName()+" 身份证号:"+person.getId()+"交钱:"+person.getMoney()+"块,开始上机...");
queue.offer(person);
}
/**
* 顾客下机
* @param person
*/
void offlineNet(Person person){
System.out.println("顾客:"+person.getName()+" 身份证号:"+person.getId()+"时间已到,开始下机...");
}
@Override
public void run() {
while (isRun) {
try {
// 持续获取,如果获取不到则将继续获取
Person person = queue.take();
// 获得人员之后,开始让他下线
offlineNet(person);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
NetBar netBar = new NetBar();
System.out.println("网吧开始营业");
new Thread(netBar).start();
netBar.surfNet(new Person("张三",2,4));
netBar.surfNet(new Person("李四",2,4));
netBar.surfNet(new Person("王五",2,4));
netBar.surfNet(new Person("路六",2,4));
}
}
网吧开始营业
顾客:张三 身份证号:2交钱:0块,开始上机...
顾客:李四 身份证号:2交钱:0块,开始上机...
顾客:王五 身份证号:2交钱:0块,开始上机...
顾客:路六 身份证号:2交钱:0块,开始上机...
=============
顾客:张三 身份证号:2时间已到,开始下机...
顾客:路六 身份证号:2时间已到,开始下机...
顾客:王五 身份证号:2时间已到,开始下机...
顾客:李四 身份证号:2时间已到,开始下机...