6种延迟队列的实现方式

1. DelayQueue 延时队列

DelayQueue 是 Java 并发包 java.util.concurrent 下的一个线程安全的阻塞队列,它存储的元素必须实现 Delayed 接口,以便计算元素的延时时间。队列中的元素只有在其指定的延迟时间到达之后才能从队列中取出。

 

arduino

代码解读

复制代码

import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class Order implements Delayed {     private long time;     private String name;     public Order(String name, long delay, TimeUnit unit) {         this.name = name;         this.time = System.currentTimeMillis() + unit.toMillis(delay);     }     @Override     public long getDelay(TimeUnit unit) {         long delay = time - System.currentTimeMillis();         return unit.convert(delay, TimeUnit.MILLISECONDS);     }     @Override     public int compareTo(Delayed other) {         if (this.time < ((Order) other).time) {             return -1;         } else if (this.time > ((Order) other).time) {             return 1;         }         return 0;     } } public class DelayQueueDemo {     public static void main(String[] args) throws InterruptedException {         DelayQueue<Order> delayQueue = new DelayQueue<>();         delayQueue.put(new Order("Order1", 5, TimeUnit.SECONDS));         delayQueue.put(new Order("Order2", 10, TimeUnit.SECONDS));         delayQueue.put(new Order("Order3", 15, TimeUnit.SECONDS));         System.out.println("订单延迟队列开始时间:" + java.time.LocalDateTime.now());         while (delayQueue.size() != 0) {             Order order = delayQueue.take(); // 阻塞直到元素可用             System.out.format("订单: %s 被取消, 取消时间: %s\n", order.name, java.time.LocalDateTime.now());         }     } }

2. Quartz 定时任务

Quartz 是一个开源的任务调度库,可以集成到几乎任何Java应用中,用于定时执行任务。通过定义任务和触发器,可以很容易地实现定时任务。

 

java

代码解读

复制代码

import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; public class QuartzJob extends QuartzJobBean {     @Override     protected void executeInternal(JobExecutionContext context) throws JobExecutionException {         System.out.println("执行定时任务: " + System.currentTimeMillis());     } } // 在 Spring 配置文件中配置 Quartz // ...

3. Redis sorted set

Redis 的有序集合(sorted set)可以利用 score 来实现延时队列。通过设置元素的 score 为过期时间戳,可以实现在特定时间自动过期并被消费。

 

vbnet

代码解读

复制代码

import redis.clients.jedis.Jedis; public class RedisDelayQueue {     private static final String DELAY_QUEUE = "delayQueue";     public void addToQueue(String key, long delaySeconds) {         double score = System.currentTimeMillis() / 1000 + delaySeconds;         new Jedis().zadd(DELAY_QUEUE, score, key);     }     public void consume() {         long now = System.currentTimeMillis() / 1000;         while (true) {             Set<String> keys = new Jedis().zrangeByScore(DELAY_QUEUE, 0, now);             for (String key : keys) {                 new Jedis().zrem(DELAY_QUEUE, key);                 System.out.println("消费元素: " + key);             }             if (keys.isEmpty()) {                 try {                     Thread.sleep(1000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         }     } }

4. Redis 过期回调

Redis 可以配置过期事件通知,当一个键过期时,Redis 会发送一个事件通知给订阅了该事件的客户端。

整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处即可】免费获取

kotlin

代码解读

复制代码

import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; public class RedisKeyExpirationListener implements MessageListener {     @Override     public void onMessage(Message message, byte[] pattern) {         String expiredKey = new String(message.getBody());         System.out.println("监听到key:" + expiredKey + "已过期");     } } // 在 Spring 配置中配置 RedisMessageListenerContainer // ...

5. RabbitMQ 延时队列

RabbitMQ 通过消息的 TTL(Time To Live)和死信交换机(DLX)来实现延时队列。

 

arduino

代码解读

复制代码

import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.core.Message; public class RabbitMQDelayQueue {     private final RabbitTemplate rabbitTemplate;     public RabbitMQDelayQueue(RabbitTemplate rabbitTemplate) {         this.rabbitTemplate = rabbitTemplate;     }     public void sendDelayedMessage(String message, long delay) {         Message msg = new Message(message.getBytes(), new MessageProperties() {             {                 setExpiration(String.valueOf(delay));                 // 设置消息的其他属性             }         });         rabbitTemplate.send("delayQueueExchange", "delayQueueRoutingKey", msg);     }     // 配置交换机、队列和绑定     // ... }

6. 时间轮算法

时间轮算法是一种高效的定时任务管理算法,Netty 提供了 HashedWheelTimer 来实现时间轮。

 

java

代码解读

复制代码

import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import io.netty.util.TimerTask; public class NettyDelayQueue {     public static void main(String[] args) {         Timer timer = new HashedWheelTimer();         timer.newTimeout(new TimerTask() {             @Override             public void run(Timeout timeout) throws Exception {                 System.out.println("任务执行: " + System.currentTimeMillis());             }         }, 5, TimeUnit.SECONDS);     } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值