千家信息网

如何实现Java中的延迟队列

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,小编给大家分享一下如何实现Java中的延迟队列,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!常见的实现方法主要有:定时任务扫描、RocketMQ延迟队列、Java自动的延迟队列、监听
千家信息网最后更新 2025年02月01日如何实现Java中的延迟队列

小编给大家分享一下如何实现Java中的延迟队列,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

常见的实现方法主要有:定时任务扫描、RocketMQ延迟队列、Java自动的延迟队列、监听Redis Key过期等等

1. DelayQueue

首先,定义一个延迟任务

package com.cjs.example;import lombok.Data;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;/** * @author ChengJianSheng * @since 2021/3/18 */@Datapublic class DelayTask implements Delayed { private Long orderId; private long expireTime; public DelayTask(Long orderId, long expireTime) {  this.orderId = orderId;  this.expireTime = expireTime; } @Override public long getDelay(TimeUnit unit) {  return expireTime - System.currentTimeMillis(); } @Override public int compareTo(Delayed o) {  return (int) (getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS)); }}

然后,定义一个管理类

package com.cjs.example;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;import java.util.concurrent.DelayQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * @author ChengJianSheng * @since 2021/3/19 */@Slf4j@Componentpublic class DelayQueueManager implements CommandLineRunner { private DelayQueue queue = new DelayQueue<>(); @Autowired private ParkOrderQueryHandler handler; @Override public void run(String... strings) throws Exception {  ExecutorService executorService = Executors.newSingleThreadExecutor();  executorService.execute(new Runnable() {   @Override   public void run() {    while (true) {     try {      DelayTask task = queue.take();      handler.handle(task);     } catch (InterruptedException e) {      e.printStackTrace();     }    }   }  }); } public void put(DelayTask task) {  queue.put(task); }}

插入任务

@Slf4j@Servicepublic class PayServiceImpl implements PayService { @Autowired private DelayQueueManager delayQueueManager; @Override public void pay() {    delayQueueManager.put(new DelayTask(1, 15));  delayQueueManager.put(new DelayTask(2, 30));  delayQueueManager.put(new DelayTask(3, 60)); }}

2. Redis Key过期回调

修改redis.conf文件

# bind 127.0.0.1 -::1
protected-mode no
notify-keyspace-events Ex

[root@localhost redis-6.2.1]$ src/redis-server redis.conf  4.0.0   org.springframework.boot  spring-boot-starter-parent  2.4.4     com.example demo0401 0.0.1-SNAPSHOT demo0401 Demo project for Spring Boot   1.8       org.springframework.boot   spring-boot-starter-data-redis             org.springframework.boot    spring-boot-maven-plugin      

RedisConfig.java

package com.example.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.listener.RedisMessageListenerContainer;/** * @author ChengJianSheng * @since 2021/4/2 */@Configurationpublic class RedisConfig { @Bean public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {  RedisMessageListenerContainer container = new RedisMessageListenerContainer();  container.setConnectionFactory(connectionFactory);  return container; }}

创建一个监听类

package com.example.listener;import org.springframework.data.redis.connection.Message;import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;import org.springframework.data.redis.listener.RedisMessageListenerContainer;import org.springframework.stereotype.Component;/** * @author ChengJianSheng * @since 2021/4/2 */@Componentpublic class MyRedisKeyExpirationListener extends KeyExpirationEventMessageListener { public MyRedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {  super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) {  String expiredKey = message.toString();  System.out.println("监听到Key: " + expiredKey + " 已过期"); }}

看完了这篇文章,相信你对"如何实现Java中的延迟队列"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

0