MST

星途 面试题库

面试题:Java DelayQueue应用场景及实现细节

在实际项目中,你能列举出哪些适合使用DelayQueue的场景?并且详细描述如何自定义一个实现Delayed接口的类,并将其用于DelayQueue中进行延迟任务处理。
14.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

适合使用DelayQueue的场景

  1. 缓存清理:在缓存系统中,为每个缓存对象设置一个过期时间。当缓存对象过期后,需要将其从缓存中移除。可以使用DelayQueue来管理这些缓存对象,当过期时间到达时,将过期的缓存对象从缓存中移除。
  2. 任务调度:在任务调度系统中,需要在指定的时间点执行某些任务。可以将这些任务封装成实现Delayed接口的对象,放入DelayQueue中,当到达任务执行时间时,从队列中取出任务并执行。
  3. 限时操作:在一些需要限时处理的场景中,例如限时支付、限时抢购等。可以将这些操作封装成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();
            }
        }
    }
}

在上述代码中:

  1. DelayedTask类:实现了Delayed接口,包含任务名称、延迟时间和过期时间。getDelay方法返回剩余延迟时间,compareTo方法用于在队列中进行排序,确保按过期时间先后出队。execute方法是任务具体的执行逻辑。
  2. DelayQueueExample类:在main方法中,创建了一个DelayQueue,并向其中添加了两个延迟任务。通过while循环从队列中取出任务并执行,take方法会阻塞直到有任务到期。