最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅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中延时队列的使用的更多相关文章

  1. Java 中的队列 Queue

    一.队列的定义 我们都知道队列(Queue)是一种先进先出(FIFO)的数据结构,Java中定义了java.util.Queue接口用来表示队列.Java中的Queue与List.Set属于同一个级别 ...

  2. java中有界队列的饱和策略(reject policy)

    文章目录 AbortPolicy DiscardPolicy DiscardOldestPolicy CallerRunsPolicy 使用Semaphore java中有界队列的饱和策略(rejec ...

  3. java中使用队列:java.util.Queue (转)

    Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Queue接 口.Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类 ...

  4. java中的队列

    转载自:http://blog.csdn.net/guijava/article/details/3784658 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.Qu ...

  5. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  6. Java中的队列:java.util.Queue接口

    队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作. Queue接口与List.Set同一级别,都是继承了Collection接口.Linked ...

  7. java中线程队列BlockingQueue的用法

    在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文 ...

  8. java中使用队列:java.util.Queue

    在java5中新添加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口.Queue使用时要尽量避免Collection的add()和 ...

  9. Java中的队列同步器AQS

    一.AQS概念 1.队列同步器是用来构建锁或者其他同步组件的基础框架,使用一个int型变量代表同步状态,通过内置的队列来完成线程的排队工作. 2.下面是JDK8文档中对于AQS的部分介绍 public ...

随机推荐

  1. docker镜像与容器的导出导入

    导入导出涉及的命令有save.load.export.import # 1) docker save 导出镜像到文件 docker save -o nginx.tar nginx:latest # 2 ...

  2. ysoserial CommonsColletions3分析(1)

    CC3的利用链在JDK8u71版本以后是无法使用的,具体还是由于AnnotationInvocationHandler的readobject进行了改写. 而CC3目前有两条主流的利用链,利用Trans ...

  3. ldconfig与 /etc/ld.so.conf

    现在我们知道了动态与静态函数库,也知道了当前的Linux大多是将函数库做成动态函数库,下面来讨论增加函数库读取性能的方法.我们知道,内存的访问速度是硬盘的好几倍,所以,如果将常用的动态函数库加载到内存 ...

  4. Windows Server 2022 OVF(SLIC 2.6)

    请访问原文链接:https://sysin.org/blog/windows-server-2022-ovf/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页:ww ...

  5. 308 day06_线程、同步

      day06 [线程.同步] 主要内容 线程 同步 线程状态 教学目标 能够描述Java中多线程运行原理 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 ...

  6. sql语句异常向数据库插入数据报错

    在php编程向数据库插入数据时报如下错误: [Err] 1064 - You have an error in your SQL syntax; check the manual that corre ...

  7. pygame简单小游戏 移动小球

    键盘a,d,s,w移动小球 需要安装pygame cmd里输入pip install pygame import pygame import sys pygame.init() screen = py ...

  8. Jmeter扩展组件开发(3) - 实现方法

    继承JavaSamplerClient,四种实现方法讲解 前提 JavaSamplerClient要把四种实现方法都继承,编译器才不会报错. com.demo(package包)右键新建一个secon ...

  9. Docker系列(3)- 配置阿里云镜像加速

    step-1 登录阿里云找到容器服务 step-2 找到镜像加速地址 step-3 配置使用 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon ...

  10. jmeter 元件详细介绍

    一.基本介绍 可以进行功能测试.性能测试.自动化测试. 二.配置元件介绍 线程组:threads 虚拟用户数,设置Jmeter按照什么场景运行,是一系列线程的集合,每一个线程都代表一个正在使用应用程序 ...