创建一个 Delayed 抽象类并且实现Runnable接口

/*** 延迟任务抽象*/
public abstract class Task implements Delayed, Runnable{private String id = "";private long start = 0;/**** @param id 任务ID, 用于区分不同任务* @param delayInMilliseconds 延迟毫秒*/public Task(String id, long delayInMilliseconds){this.id = id;this.start = System.currentTimeMillis() + delayInMilliseconds;}public String getId() {return id;}@Overridepublic long getDelay(TimeUnit unit) {long diff = this.start - System.currentTimeMillis();return unit.convert(diff, TimeUnit.MILLISECONDS);}@Overridepublic int compareTo(Delayed o) {System.out.println(" this.start = " + this.start);System.out.println(" Delayed.start = " + ((Task) o).start);return Ints.saturatedCast(this.start - ((Task) o).start);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null) return false;if (!(o instanceof Task)) {return false;}Task t = (Task)o;return this.id.equals(t.getId());}@Overridepublic int hashCode() {return this.id.hashCode();}
}

创建一个 延迟任务队列

/*** 延迟任务队列*/
@Component
public class TaskService {private TaskService taskService;private DelayQueue<Task> delayQueue =  new DelayQueue<Task>();@PostConstructprivate void init() {// 当前类初始化执行这个方法, 循环取 队列中的任务taskService = this;Executors.newSingleThreadExecutor().execute(new Runnable() {@Overridepublic void run() {while (true) {try {Task task = delayQueue.take();task.run();} catch (Exception e) {e.printStackTrace();}}}});}public void addTask(Task task){if(delayQueue.contains(task)){return;}delayQueue.add(task);}public void removeTask(Task task){delayQueue.remove(task);}}

使用

1、创建一个 延迟10秒发送 消息的任务

@Slf4j
public class SendMessageTask extends Task {/*** 用户ID*/private Integer userId = -1;public OrderTimeOutTask(Integer id, long delayInMilliseconds) {super("OrderTimeOutTask-" + id , delayInMilliseconds);this.orderId = id;}@Overridepublic void run() {log.info("延迟10秒向用户ID: 【{}】 发送消息", this.userId );}
}

2、创建延迟任务

    @Autowiredprivate TaskService taskService;@Testpublic void test(){// 延迟10 秒LocalDateTime now = LocalDateTime.now();LocalDateTime nowB = now.plusSeconds(10);// 计算两个时间相差毫秒数long betweenMillis =  ChronoUnit.MILLIS.between(now , nowB );// 新增一个延迟任务到队列中taskService.addTask(new SendMessageTask(12580, betweenMillis ));}

后期考虑到系统重启后任务会丢失,可以在系统启动的时候把所有任务重新加入到队列中

示例

/*** 用于处理 程序重启 之后 继续处理延迟任务*/
@Component
@Order(1)
public class TaskStartupRunner implements ApplicationRunner {private static Logger log = LoggerFactory.getLogger(TaskStartupRunner.class);@Autowiredprivate TaskService taskService;@Overridepublic void run(ApplicationArguments args) throws Exception {ThreadUtil.execAsync(new Runnable() {@Overridepublic void run() {SendMessageTask();}});}public void SendMessageTask(){if(消息创建时间 大于当前时间){// 立即执行延迟任务taskService.addTask(new SendMessageTask(12580, 0));}else{// 消息创建时间 还没有超出 延迟时间,计算出当前时间和延迟时间long betweenMs =  ChronoUnit.MILLIS.between(now , nowB);taskService.addTask(new OrderTimeOutTask(12580, betweenMs));}}}

Java使用 Delayed 实现延迟任务相关推荐

  1. java延迟队列,java高级面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  2. SpringCloud微服务项目实战 - 6.延迟任务

    我没有失约,我与春风共至,我与夏蝉共鸣,我与秋叶共舞,我与凛冬共至,唯独你背道而行! 系列文章目录 项目搭建 App登录及网关 App文章 自媒体平台(博主后台) 内容审核(自动) 延迟任务 - 精准 ...

  3. Java 9推迟6个月发布?

    近日,来自于Oracle的Java首席架构师Mark Reinhold提议推迟Java 9的发布时间. \\ 目前的计划是到今年12月10日实现Java 9的特性完备,从而为明年9月GA版的发布预留出 ...

  4. Java多线程和并发问题集

    并发是指什么 并发是程序同时执行多个计算的能力. 这可以通过将计算分布在机器的可用CPU内核上(多核CPU支持)或甚至通过同一网络内的不同机器来实现(后台分布式). 进程和线程有什么区别 进程是操作系 ...

  5. 来,跟我一起撸Kotlin runBlocking/launch/join/async/delay 原理使用

    前言 协程系列文章: 一个小故事讲明白进程.线程.Kotlin 协程到底啥关系? 少年,你可知 Kotlin 协程最初的样子? 讲真,Kotlin 协程的挂起/恢复没那么神秘(故事篇) 讲真,Kotl ...

  6. 【原创】Kakfa utils源代码分析(一)

    Kafka.utils,顾名思义,就是一个工具套件包,里面的类封装了很多常见的功能实现--说到这里,笔者有一个感触:当初为了阅读Kafka源代码而学习了Scala语言,本以为Kafka的实现会用到很多 ...

  7. 【消息队列之Beanstalk】

    Beanstalk is a simple, fast work queue. Its interface is generic, but was originally designed for re ...

  8. Java如何解决mysql读写延迟_java中延迟任务的处理方式

    1.利用延迟队列 延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到-- 应用场景比较多, ...

  9. java中延迟任务的处理方式

    1.利用延迟队列 延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到-- 应用场景比较多, ...

最新文章

  1. ABAP之Screen
  2. Shell命令-Sort,Join
  3. 现有工程项目上加响应式
  4. 十万个为什么之为什么大家都说dubbo
  5. 张季跃 201771010139《面向对象程序设计(java)》第十三周学习总结
  6. linux上调用短信接口,短信猫接口程序Gnokii For Linux安装
  7. easyui添加删除表格任意行
  8. zk - zookeeper实现配置中心
  9. feedsky绑定二级域名不能更新解决方法
  10. 物质环境、符号还是认知模型?——谈韩礼德、马丁、范迪克的语境观
  11. 采样频率,采样率,转换速率
  12. springboot注解实现自动插入创建时间和更新时间到数据库
  13. win7系统 将 IE11 改为 IE8
  14. 综合布线系统施工规范
  15. elasticsearch学习之字段统计
  16. mysql创建序列发生器_字符控制发生器可以干啥
  17. http——学习记录
  18. Transfer Learning Toolkit (TLT) + DeepStream (DS)快速部署深度学习模型(以口罩检测为例)
  19. Python异步任务模块之-celery
  20. Unity3D使用腾讯广点通广告

热门文章

  1. Flutter 的越界banner/思维定势
  2. 【华为OD机试真题】羊、狼、农夫过河(狼羊过河)(c++javapython)
  3. 2021最新版的成语小程序源码 内附教程
  4. css文本两端对齐text-algin:justify兼容IE写法
  5. CAD查找图上的文字(com接口)
  6. 做分销,远比你想的要难的多
  7. php使用curl下载文件
  8. OA系统如何实现严谨的费用报销流程
  9. 【Effective Objective-C 2.0读书笔记】第六章:块(Blocks)和大中枢派发(GCD)
  10. 简单的无理函数的不定积分