【SpringBoot】调度和执行定时任务--DelayQueue (附demo)

DelayQueue 是 Java 中 java.util.concurrent 包的一部分,它是一个无界阻塞队列,其中的元素只能在其到期时才能被取出。DelayQueue 是一个泛型类,要求队列中的元素实现 Delayed 接口。

1. Delayed 接口

要使用 DelayQueue,首先需要实现 Delayed 接口。Delayed 接口继承自 Comparable 接口,要求实现以下两个方法:

  • long getDelay(TimeUnit unit): 返回剩余的延迟时间。
  • int compareTo(Delayed o): 比较两个延迟对象的顺序。

2. 创建一个 Delayed 元素

下面是一个简单的实现 Delayed 接口的类:

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

public class DelayedElement implements Delayed {
    private final long delayTime;
    private final long expireTime;
    private final String message;

    public DelayedElement(long delayTime, String message) {
        this.delayTime = delayTime;
        this.expireTime = System.currentTimeMillis() + delayTime;
        this.message = message;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = expireTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        if (this.expireTime < ((DelayedElement) o).expireTime) {
            return -1;
        }
        if (this.expireTime > ((DelayedElement) o).expireTime) {
            return 1;
        }
        return 0;
    }

    public String getMessage() {
        return message;
    }
}

3. 使用 DelayQueue

创建一个 DelayQueue 并添加 Delayed 元素:

import java.util.concurrent.DelayQueue;

public class DelayQueueExample {
    public static void main(String[] args) throws InterruptedException {
        DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();

        // 添加延迟元素到队列中
        delayQueue.put(new DelayedElement(5000, "Message 1")); // 5秒延迟
        delayQueue.put(new DelayedElement(10000, "Message 2")); // 10秒延迟
        delayQueue.put(new DelayedElement(15000, "Message 3")); // 15秒延迟

        // 取出元素
        while (!delayQueue.isEmpty()) {
            DelayedElement element = delayQueue.take(); // 阻塞,直到有元素到期
            System.out.println("Received: " + element.getMessage());
        }
    }
}

4. 常用方法

DelayQueue 提供了一些常用的方法:

  • boolean add(E e): 添加元素到队列中。
  • boolean offer(E e): 尝试添加元素到队列中。
  • void put(E e): 添加元素到队列中,如果队列已满则阻塞。
  • E take(): 取出并移除队列头部的元素,如果没有元素到期则阻塞。
  • E poll(): 取出并移除队列头部的元素,如果没有元素到期返回 null
  • E peek(): 获取队列头部的元素,但不移除,如果没有元素到期返回 null
  • int size(): 返回队列中元素的数量。

5. 示例:使用 DelayQueue 实现延迟任务调度

下面是一个使用 DelayQueue 实现延迟任务调度的示例:

import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DelayQueueScheduler {
    private final DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();
    private final ExecutorService executor = Executors.newSingleThreadExecutor();

    public DelayQueueScheduler() {
        executor.execute(() -> {
            try {
                while (true) {
                    DelayedElement element = delayQueue.take();
                    System.out.println("Executing task: " + element.getMessage());
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
    }

    public void scheduleTask(long delay, String message) {
        delayQueue.put(new DelayedElement(delay, message));
    }

    public void shutdown() {
        executor.shutdown();
    }

    public static void main(String[] args) throws InterruptedException {
        DelayQueueScheduler scheduler = new DelayQueueScheduler();
        scheduler.scheduleTask(5000, "Task 1"); // 5秒后执行
        scheduler.scheduleTask(10000, "Task 2"); // 10秒后执行
        scheduler.scheduleTask(15000, "Task 3"); // 15秒后执行

        Thread.sleep(20000); // 主线程等待20秒
        scheduler.shutdown();
    }
}

6. 注意事项

  • DelayQueue 是无界队列,因此在使用时要小心避免内存泄漏。
  • DelayQueue 中的元素必须实现 Delayed 接口,否则无法正常工作。
  • DelayQueuetake 方法是阻塞的,会一直等待直到有元素到期。

通过这些详细的用法和示例,你可以了解如何在Java中使用 DelayQueue 来实现延迟任务调度。根据具体需求选择合适的调度方法和处理策略。

Spring Boot中的Delay Queue延时队列)是一种用于处理延时任务的机制。延时任务指的是需要在一定时间后才能执行任务Spring Boot延时队列的实现主要借助了Spring的TaskScheduler来实现。TaskScheduler是Spring提供的任务调度器,可以用来执行延时任务。 为了使用延时队列,我们首先需要配置一个TaskScheduler。可以通过在配置类中添加@Bean注解来创建一个TaskScheduler的Bean。配置类内容如下: ``` @Configuration public class AppConfig { @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(5); scheduler.setThreadNamePrefix("TaskScheduler-"); return scheduler; } } ``` 上述配置创建了一个线程池大小为5的TaskScheduler对象,并且设置了线程名称前缀为"TaskScheduler-"。 接下来,我们可以创建一个延时任务,通过在方法上添加@Scheduled注解,并设置fixedDelay属性来定义延时的时间间隔,单位为毫秒。例如: ``` @Component public class DelayedTask { @Scheduled(fixedDelay = 5000) public void executeDelayedTask() { //延时任务执行逻辑 System.out.println("执行延时任务"); } } ``` 上述代码中,executeDelayedTask方法使用@Scheduled注解来标识为定时任务,并设置fixedDelay为5000,表示延时5秒后执行任务。 最后,通过在启动类上添加@EnableScheduling注解来启用Spring任务调度功能。即可实现延时任务执行。 总结来说,Spring Boot中的Delay Queue延时队列)是通过配置TaskScheduler来实现的。我们可以通过在方法上添加@Scheduled注解,并设置fixedDelay属性来定义延时间隔,然后在启动类上添加@EnableScheduling注解来启用任务调度功能,从而实现延时任务执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值