面试题答案
一键面试适合使用DelayQueue的场景
- 缓存清理:在缓存系统中,为每个缓存对象设置一个过期时间。当缓存对象过期后,需要将其从缓存中移除。可以使用DelayQueue来管理这些缓存对象,当过期时间到达时,将过期的缓存对象从缓存中移除。
- 任务调度:在任务调度系统中,需要在指定的时间点执行某些任务。可以将这些任务封装成实现Delayed接口的对象,放入DelayQueue中,当到达任务执行时间时,从队列中取出任务并执行。
- 限时操作:在一些需要限时处理的场景中,例如限时支付、限时抢购等。可以将这些操作封装成Delayed对象放入DelayQueue,当超过限定时间,进行相应的处理,比如取消订单等。
自定义实现Delayed接口的类并用于DelayQueue
以下是Java代码示例:
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
// 自定义实现Delayed接口的类
class DelayedTask implements Delayed {
private final long delayTime;
private final long expireTime;
private String taskName;
public DelayedTask(String taskName, long delayTime) {
this.taskName = taskName;
this.delayTime = delayTime;
this.expireTime = System.currentTimeMillis() + delayTime;
}
// 获取剩余延迟时间
@Override
public long getDelay(TimeUnit unit) {
long diff = expireTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
// 用于队列内部比较排序
@Override
public int compareTo(Delayed other) {
if (this.expireTime < ((DelayedTask) other).expireTime) {
return -1;
}
if (this.expireTime > ((DelayedTask) other).expireTime) {
return 1;
}
return 0;
}
public void execute() {
System.out.println("执行任务: " + taskName);
}
}
public class DelayQueueExample {
public static void main(String[] args) {
DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
// 添加任务到队列
delayQueue.add(new DelayedTask("任务1", 3000));
delayQueue.add(new DelayedTask("任务2", 1000));
// 模拟处理任务
while (!delayQueue.isEmpty()) {
try {
DelayedTask task = delayQueue.take();
task.execute();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在上述代码中:
- DelayedTask类:实现了Delayed接口,包含任务名称、延迟时间和过期时间。
getDelay
方法返回剩余延迟时间,compareTo
方法用于在队列中进行排序,确保按过期时间先后出队。execute
方法是任务具体的执行逻辑。 - DelayQueueExample类:在
main
方法中,创建了一个DelayQueue
,并向其中添加了两个延迟任务。通过while
循环从队列中取出任务并执行,take
方法会阻塞直到有任务到期。