DelayQueue是一个元素具有延迟属性的无界队列。它的元素必须实现Delayed接口,当过期时间到了的时候,才能获取到这个元素,进行操作。它的使用场景很多,都是涉及到延迟过期相关业务的,比如redis缓存、系统内存数据过期等等。
下面模拟网吧上网的场景。网民去网吧上网,交钱获取上网时间就能上机,时间到下机,就是这个场景。
首先,定义网民对象,实现Delayed接口,重写里面的方法。
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class WangMin implements Delayed{
//身份证
private String id;
//名字
private String name;
//上网截至时间
private long endTime;
//时间戳单位
private TimeUnit timeUnit;
public WangMin() {
}
public WangMin(String id, String name, long endTime) {
this.id = id;
this.name = name;
this.endTime = endTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
/**判断是否下机时间到了*/
@Override
public int compareTo(Delayed delayed) {
WangMin wm = (WangMin)delayed;
return this.getDelay(this.timeUnit) - wm.getDelay(this.timeUnit) > 0 ? 1 : 0;
}
/**还剩下多少上机时间*/
@Override
public long getDelay(TimeUnit unit) {
return this.endTime - System.currentTimeMillis();
}
}
定义网吧对象,实现Runnable接口,重写run方法,里面需定义DelayQueue成员变量来接受网民对象,定义上机下机的方法。
import java.util.concurrent.DelayQueue;
public class WangBa implements Runnable{
private DelayQueue<WangMin> delayQueue = new DelayQueue<>();
//网吧是否开门营业
private boolean isOpen = true;
/**开始上机*/
public void startMachine(String id, String name ,int money) {
WangMin wm = new WangMin(id, name, money * 1000 + System.currentTimeMillis());
System.err.println("网名:" + name + " ,身份证:" + id + " ,缴费 " + money + " 元,开始上机。");
delayQueue.add(wm);
}
/**下机*/
public void endMachine(WangMin wm) {
System.err.println("网名:" + wm.getName() + " ,身份证:" + wm.getId() + " ,网费时间到了,已下机。");
}
@Override
public void run() {
while(isOpen) {
try {
//获取网民对象,监控上网情况。只有当有网民上机时间过期的时候,才能获取到网民对象。
WangMin wm = delayQueue.take();
//执行下机操作
endMachine(wm);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
main方法中测试:
public static void main(String[] args) {
WangBa wangBa = new WangBa();
wangBa.startMachine("001", "张三", 3);
wangBa.startMachine("002", "李四", 5);
wangBa.startMachine("003", "王五", 10);
new Thread(wangBa).start();
}
可见经过一段时间,三个网民对象相应下机。