最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅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 实现延迟队列的方法,文中讲解非常详细,供大家参考和学习,感兴趣的朋友可以了解下
redis的sorted set实现延时队列
主要介绍了一口气说出Java 6种延时队列的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
主要给大家介绍了java利用delayedQueue实现本地的延迟队列的相关资料,文中介绍的非常详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
整个延迟队列由4个部分组成: 1. JobPool用来存放所有Job的元信息。 2. DelayBucket是一组以时间为维度的有序队列,用来存放所有需要延迟的Job(这里只存放Job Id)。 3. Timer负责实时扫描各个Bucket,并将delay...
将整个Redis当做消息池,以kv形式存储消息 使用ZSET做优先队列,按照score维持优先级
多层时间轮,可根据配置的时间轮大小参数以及插入任务的相对时间,动态地创建不同层次的时间轮实例(这里的多层时间轮采用了...引入了延时队列以减少空轮询,将时间轮的推进与任务的提交执行隔离开,提升模型的效率。
该工具使用DeplayQueue延时队列作为软件架构,通过简单的步骤即可完成安装和使用。首先,你需要创建一个实现LsDelayed接口的任务类,并设置任务的名称和执行时间戳。然后,通过CronDelayQueue的init方法初始化任务...
java使用DelayQueue延迟队列和Redis缓存实现订单自动取消功能
主要介绍了Java延迟队列原理与用法,结合实例形式详细分析了延迟队列的概念、原理、功能及具体使用方法,需要的朋友可以参考下
何为延迟队列?顾名思义,延迟队列就是进入该队列的消息会被延迟消费的队列。而一般的队列,消息一旦...如果不使用延迟队列,那么我们只能通过一个轮询扫描程序去完成。这种方案既不优雅,也不方便做成统一的服务便于
2.8 在锁中使用多条件(Multiple Condition) 69 第3章 线程同步辅助类 77 3.1 简介 77 3.2 资源的并发访问控制 78 3.3 资源的多副本的并发访问控制 83 3.4 等待多个并发事件的完成 87 3.5 在集合...
rabbitmq-pubsub-java“RabbitMQ发布订阅实战-实现延时重试队列”一文的java代码示例
环形队列是一个实现“延时消息”的好方法,开源的MQ好像都不支持延迟消息,不妨自己实现一个简易的“延时消息队列”,能解决很多业务问题,并减少很多低效扫库的cron任务。
6.如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决? 7.如果让你写一个消息队列,该如何进行架构设计?说一下你的思路。 8.es 的分布式架构原理能...
为什么使用消息队列? 如何保证消息队列的高可用? 如何保证消息不被重复消费? 如何保证消息的可靠性传输? 如何保证消息的顺序性? 如何解决消息队列的延时以及过期失效问题? 如何设计一个消息队列? 搜索引擎 ...
1.延迟消息BUG:延时消息基于jdk自带的delayQueue实现,系统宕机重启后服务端读取leveldb中的消息后将消息重新放回延时队列,会重新设置到期时间。例如:设置一条消息5分钟后推送,中途系统宕机,系统重启后会从当前...
主要介绍了ScheduledExecutorService任务定时代码示例,具有一定借鉴价值,需要的朋友可以参考下
在队列中有多少个(How Many)任务在等待执行? 如果系统由于过载而需要拒绝一个任务,那么应该选择哪一个(Which)任务?另外,如何(How)通知应用程序有任务被拒绝? 在执行一个任务之前或之后,...
使用方法 配置broker.conf segmentScale=60 ##每个时间桶的时间范围,单位分钟,默认60,可选值0-60之间,延迟消息并发数越高,配置的值应该越小,如:10 dispatchLogKeepTime=72 ##dispatchLog过期后保存的小时数,...