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); } }