最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送。在翻阅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. 第08课:GDB 实用调试技巧( 上)

    本节课的核心内容: 将 print 打印结果显示完整 让被 GDB 调试的程序接收信号 函数明明存在,添加断点时却无效 将 print 打印结果显示完整 当使用 print 命令打印一个字符串或者字符 ...

  2. Go并发编程--正确使用goroutine

    目录 1. 对创建的gorouting负载 1.1 不要创建一个你不知道何时退出的 goroutine 1.1.1 不要帮别人做选择 1.1.2 不要作为一个旁观者 1.1.3 不要创建不知道什么时候 ...

  3. 【第九篇】- Git 标签之Spring Cloud直播商城 b2b2c电子商务技术总结

    Git 标签 如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签. 比如说,我们想为我们的 xxx 项目发布一个"1.0"版本. ...

  4. Spring Boot中使用@Async的时候,千万别忘了线程池的配置!

    上一篇我们介绍了如何使用@Async注解来创建异步任务,我可以用这种方法来实现一些并发操作,以加速任务的执行效率.但是,如果只是如前文那样直接简单的创建来使用,可能还是会碰到一些问题.存在有什么问题呢 ...

  5. 微信小程序view不能换行 text实现转义换行符

    在html中可以直接使用<br />换行,但是小程序wxml中使用<br />无效,可以换成\n Page({ data: { title: '至少5个字\n请多说些感受吧' ...

  6. 3gcms导航,实现当前栏目高亮的办法

    <volist name="menu" id="vo" offset="0" length='8' key='k'> <l ...

  7. dede图片集关联的数据库用表:

    如果在本地的环境中,安装目录不在根目录,搬到外网上的时候,就需要对数据库里的图片路径数据进行字段替换: dede图片集关联的数据库用表:1.dede_addonimages 2.dede_arctin ...

  8. python刷题第二周

    1: 第3章-5 字符转换 (15 分) 本题要求提取一个字符串中的所有数字字符('0'--'9'),将其转换为一个整数输出. 输入格式: 输入在一行中给出一个不超过80个字符且以回车结束的字符串. ...

  9. django中admin一些方法

    1.概述:内容发布,负责添加,修改,删除内容及公告访问2.配置admin应用在settings文件中INSTALLED_APPS添加:'django.contrib.admin', 默认是已经添加好的 ...

  10. three.js 材质翻转

    刚学.这个鸟玩意儿卡了半天,记录一下. var skyBox = new THREE.Mesh(skyGeometry, skyMaterial); //创建一个完整的天空盒,填入几何模型和材质的参数 ...