详解Java中的延时队列 DelayQueue
概述
DelayQueue是Java中的一个实现了Delayed的队列,它按照剩余时间从少到多的顺序对元素进行排序,每个元素都有一个过期时间,只有过期的元素才能被取出。
延时队列的实现
延时队列的实现需要实现Delayed接口,并重写getDelay()方法和compareTo()方法。
public interface Delayed extends Comparable<Delayed> {
long getDelay(TimeUnit unit);
}
public interface Comparable<T> {
int compareTo(T o);
}
getDelay()方法返回元素还剩余的时间,compareTo()方法根据剩余时间排序。
示例1:使用DelayQueue实现定时任务调度
可以通过DelayQueue实现一个简单的定时任务调度,每个任务都有一个延时时间和执行内容。优先级较高的任务会在队列中排在前面。
public class Task implements Delayed {
private long delayTime;
private long expireTime;
private Runnable task;
public Task(long delayTime, Runnable task) {
this.delayTime = delayTime;
this.expireTime = System.currentTimeMillis() + delayTime;
this.task = task;
}
public void runTask() {
task.run();
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(expireTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.expireTime, ((Task) o).expireTime);
}
}
上述代码中,Task类实现了Delayed接口,将延时时间和执行内容封装在任务中,getDelay()方法返回剩余时间,在队列中按剩余时间排序。
public class DelayQueueDemo {
public static void main(String[] args) throws InterruptedException {
DelayQueue<Task> delayQueue = new DelayQueue<>();
delayQueue.add(new Task(1000, () -> System.out.println("task1 execute")));
delayQueue.add(new Task(1500, () -> System.out.println("task2 execute")));
delayQueue.add(new Task(500, () -> System.out.println("task3 execute")));
while (!delayQueue.isEmpty()) {
Task task = delayQueue.take();
task.runTask();
}
}
}
上述代码中,先使用DelayQueue存放任务,每个任务从队列中取出后执行。
示例2:使用DelayQueue实现超时会话
可以使用DelayQueue实现一个超时会话,每个会话都有一个过期时间,过期的会话从队列中删除。可以在WebSocket、TCP等应用中使用。
public class Session implements Delayed {
private String sessionId;
private long expireTime;
public Session(String sessionId, long expireTime) {
this.sessionId = sessionId;
this.expireTime = System.currentTimeMillis() + expireTime;
}
public String getSessionId() {
return sessionId;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(expireTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(expireTime, ((Session) o).expireTime);
}
}
上述代码中,Session类实现了Delayed接口,将sessionId和过期时间封装在会话中,getDelay()方法返回剩余时间,在队列中按剩余时间排序。
public class DelayQueueDemo {
private static DelayQueue<Session> sessionDelayQueue = new DelayQueue<>();
public static void main(String[] args) throws InterruptedException {
// 添加会话
sessionDelayQueue.add(new Session("1", 2000));
sessionDelayQueue.add(new Session("2", 1500));
sessionDelayQueue.add(new Session("3", 1000));
// 等待5s
Thread.sleep(5000);
// 取出过期会话
while (!sessionDelayQueue.isEmpty()) {
Session session = sessionDelayQueue.poll();
if (session != null) {
System.out.println(session.getSessionId() + " expire");
}
}
}
}
上述代码中,使用DelayQueue存放会话,等待5s后取出过期会话。
小结
DelayQueue是Java中一个实现了Delayed的队列,它可以用于实现定时任务调度、超时会话等业务场景,开发者可以根据具体需求进行使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java中的延时队列 DelayQueue - Python技术站