最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅java的api后,发现java中有一个延时队列可以解决这个问题。
实现思路:
1、需要延时发送消息的实体类实现 Delayed 接口,在getDelay方法中,返回这个对象还有多上时间需要执行。
2、将短信类加入到延时队列DelayQueye中
实现效果:
将短信Sms加入到队列中,到了invokedTime后从队列中直接取出执行。
主线程中启动一个子线程,打印当前时间,查看队列中的数据执行的时机是否正确。
delayqueue 的take方法,获取并移除此队列的头部,在可从此队列获得到期延迟的元素之前一直等待(如有必要)
代码如下:
@Slf4j public class DelayTest { @Data @Builder static class Sms implements Delayed { // 执行时间 private long invokedTime; // 需要发出的消息 private String smg; public static Sms build(String msg, int expireTimeSecond) { return Sms.builder().smg(msg).invokedTime(System.nanoTime() + TimeUnit.NANOSECONDS.convert(expireTimeSecond, TimeUnit.SECONDS)).build(); } /** * 返回这个对象剩余的延时时间 * * @param unit * @return */ @Override public long getDelay(TimeUnit unit) { return unit.convert(invokedTime - System.nanoTime(), TimeUnit.NANOSECONDS); } @Override public int compareTo(Delayed o) { if (o == null || !(o instanceof Sms)) return 1; if (o == this) return 0; Sms sms = (Sms) o; if (this.invokedTime > sms.invokedTime) { return 1; } else if (this.invokedTime == sms.invokedTime) { return 0; } else { return -1; } } } public static void main(String[] args) throws InterruptedException { DelayQueue<Sms> queue = new DelayQueue<>(); queue.add(Sms.build("3-hello3", 3)); queue.add(Sms.build("5-hello5", 5)); queue.add(Sms.build("2-hello2", 2)); queue.add(Sms.build("4-hello4", 1)); queue.add(Sms.build("1-hello1", 1)); new Thread(() -> { Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { log.info(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); }, 0, 1, TimeUnit.SECONDS); }).start(); Sms sms; while (null != (sms = queue.take())) { System.out.println(sms); } } }
执行结果:
相关推荐
JAVA 实现延迟队列的方法是指在 JAVA 中实现延迟队列的方法,即在特定的延迟时间后触发某个事件,这种机制广泛应用于日常开发的场景中,例如用户登录之后5分钟给用户做分类推送、用户多少天未登录给用户做召回推送、...
Java 延时队列的实现方法 延时队列是一种特殊的队列,它可以根据指定的延迟时间来消费队列中的消息。在 Java 中,实现延时队列有多种方式,以下是六种常见的实现方法: 1. DelayQueue 延时队列 DelayQueue 是 ...
在提供的文件 `delay-queue-node-master` 中,可能是使用 Node.js 编写的 Redis 延时队列实现。通常,这样的实现会包含以下部分: - 初始化 Redis 连接。 - 定义添加任务、获取和处理到期任务、删除任务等方法。 - ...
DelayQueue 能够保证队列中的对象是有序的,即队头对象的延迟到期时间最长。 DelayQueue 的使用场景非常广泛,如: 1. 订单业务中,下单之后如果三十分钟之内没有付款就自动取消订单。 2. 饿了吗订餐通知中,...
5. **消息消费**:定义一个`@RabbitListener`注解的消费方法,用于接收并处理延时队列中的消息。这里可以利用Spring的`@ServiceActivator`或`@Bean`定义多个处理策略,通过策略模式选择合适的处理方式。 6. **消费...
整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个Bucket,并将delay...
在这个"redis延时队列.zip"压缩包中,包含两个Java文件:DelayDataConsumer.java和DelayDataProducer.java,它们分别代表了延时队列的消费者和生产者角色。 首先,我们来了解Redis延时队列的基本原理。Redis本身并...
多层时间轮,可根据配置的时间轮大小参数以及插入任务的相对时间,动态地创建不同层次的时间轮实例(这里的多层时间轮采用了...引入了延时队列以减少空轮询,将时间轮的推进与任务的提交执行隔离开,提升模型的效率。
该工具使用DeplayQueue延时队列作为软件架构,通过简单的步骤即可完成安装和使用。首先,你需要创建一个实现LsDelayed接口的任务类,并设置任务的名称和执行时间戳。然后,通过CronDelayQueue的init方法初始化任务...
标题中的“延时队列”是指一种特殊类型的队列,它的主要特点是消息不会立即被处理,而是会在预定的时间延迟后才被消费。这种技术在很多场景下非常有用,例如在需要定时任务、订单超时处理或者消息缓存等方面。描述中...
当这个延迟时间到达零时,元素才可从队列中取出。在订单自动取消功能中,我们可以创建一个表示订单的类,实现Delayed接口,并设置一个代表订单超时时间的延迟值。 Redis是一个高性能的键值数据库,常用于缓存和消息...
Java延迟队列是一种特殊的队列结构,它允许元素在队列中等待一段时间,然后才能被消费。在Java中,延迟队列是通过 DelayQueue 实现的,Delayed 接口定义了延迟队列的元素必须实现的两个方法:compareTo 和 getDelay...
当消息在业务队列中处理失败,如因异常导致重试次数达到上限,就会变为死信。DLX允许将这些死信重新发布到另一个特定的Exchange,以便进行后续处理。 1. **死信队列定义** DLX是RabbitMQ中处理异常或无效消息的一...
在这个名为"rabbitmq_delayed.zip"的压缩包中,我们看到的是一个使用SpringBoot框架实现的RabbitMQ延时队列功能的示例代码。下面将详细解释RabbitMQ延时队列的工作原理以及如何在SpringBoot应用中进行集成。 延时...
4. **定时器和延时**:Java的`Timer`类或`ScheduledExecutorService`可以用来设定线程在特定时间后执行,这对应于进程在队列中的等待时间。 5. **队列数据结构**:为了实现多级队列,可能需要使用Java的`Queue`接口...
使用环形队列实现的延迟消息功能具有以下显著优点: 1. **高效性**:避免了定时任务的轮询机制,减少了不必要的数据库操作。 2. **一次性执行**:确保每个任务仅被执行一次,避免了重复计算。 3. **精确的时效性**...
何为延迟队列?顾名思义,延迟队列就是进入该队列的消息会被延迟消费的队列。而一般的队列,消息一旦...如果不使用延迟队列,那么我们只能通过一个轮询扫描程序去完成。这种方案既不优雅,也不方便做成统一的服务便于
1. 基于编程语言的解决方案:这种方案通常使用编程语言中提供的定时器、延时队列等组件。例如,Java中的Timer和DelayQueue,可以实现简单的延迟任务。但这种方法一般适用于单机场景,因为它难以应对分布式系统中的...