MST

星途 面试题库

面试题:Java中DelayQueue实现定时任务时,如何自定义任务的延迟时间逻辑?

请阐述在使用Java的DelayQueue实现定时任务场景下,若要实现基于业务逻辑动态设置每个任务延迟时间,具体该如何操作?比如在一个电商订单处理系统中,不同金额的订单设置不同的处理延迟时间,简要说明实现思路并给出关键代码片段。
22.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建一个实现 Delayed 接口的任务类,该类用于封装订单信息以及延迟时间。
  2. 在任务类中根据业务逻辑(如订单金额)计算延迟时间。
  3. 将任务类的实例放入 DelayQueue 中。
  4. 启动一个线程从 DelayQueue 中获取到期的任务并执行相应的订单处理逻辑。

关键代码片段

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

// 订单任务类,实现 Delayed 接口
class OrderTask implements Delayed {
    private long delayTime;
    private long submitTime;
    private double orderAmount;
    private String orderId;

    public OrderTask(double orderAmount, String orderId) {
        this.orderAmount = orderAmount;
        this.orderId = orderId;
        // 根据订单金额计算延迟时间,例如金额越大延迟越短
        this.delayTime = calculateDelayTime(orderAmount);
        this.submitTime = System.currentTimeMillis();
    }

    private long calculateDelayTime(double orderAmount) {
        // 简单示例,订单金额大于1000延迟1秒,小于等于1000延迟3秒
        if (orderAmount > 1000) {
            return 1000;
        } else {
            return 3000;
        }
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long remainingDelay = delayTime - (currentTime - submitTime);
        return unit.convert(remainingDelay, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed other) {
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS));
    }

    public void processOrder() {
        System.out.println("Processing order " + orderId + " with amount " + orderAmount);
    }
}

public class OrderProcessingSystem {
    public static void main(String[] args) {
        DelayQueue<OrderTask> delayQueue = new DelayQueue<>();

        // 添加订单任务
        delayQueue.add(new OrderTask(1500, "1001"));
        delayQueue.add(new OrderTask(800, "1002"));

        Thread worker = new Thread(() -> {
            while (true) {
                try {
                    OrderTask task = delayQueue.take();
                    task.processOrder();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        worker.start();
    }
}