定时任务 & 定时线程池
定时线程池
使用场景:
1. 分布式锁 - redis
2. springCloud - 服务注册与发现中心
ScheduledThreadPoolExecutor
它用来处理延时任务或定时任务。
它接收SchduledFutureTask类型的任务,是线程池调度任务的最小单位,有三种提交任务的方式:
- schedule
- scheduledAtFixedRate
- scheduledWithFixedDelay
它采用DelayQueue存储等待的任务
- DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;
- DelayQueue也是一个无界队列;
任务提交上来后,会将任务封装为一个ScheduledFutureTask
1 public void run() { 2 boolean periodic = isPeriodic(); 3 //如果当前线程池已经不支持执行任务,则取消 4 if (!canRunInCurrentRunState(periodic)) 5 cancel(false); 6 //如果不需要周期性执行,则直接执行run方法然后结束 7 else if (!periodic) 8 ScheduledFutureTask.super.run(); 9 //如果需要周期执行,则在执行完任务以后,设置下一次执行时间 10 else if (ScheduledFutureTask.super.runAndReset()) { 11 // 计算下次执行该任务的时间 12 setNextRunTime(); 13 //重复执行任务 14 reExecutePeriodic(outerTask); 15 } 16 }
1. 如果当前线程池运行状态不可以执行任务,取消该任务,然后直接返回,否则执行 步骤2;
2. 如果不是周期性任务,调用FutureTask中的run方法执行,会设置执行结果,然后 直接返回,否则执行步骤3;
3. 如果是周期性任务,调用FutureTask中的runAndReset方法执行,不会设置执行 结果,然后直接返回,否则执行步骤4和步骤5;
4. 计算下次执行该任务的具体时间;
5. 重复执行任务。
DelayedWorkQueue
ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。
ScheduledThreadPoolExecutor之所以要自己实现阻塞的工作队列,是因为 ScheduledThreadPoolExecutor要求的工作队列有些特殊。 DelayedWorkQueue是一个基于堆的数据结构,类似于DelayQueue和 PriorityQueue。在执行定时任务的时候,每个任务的执行时间都不同,所以 DelayedWorkQueue的工作就是按照执行时间的升序来排列,执行时间距离当前时间越近 的任务在队列的前面(注意:这里的顺序并不是绝对的,堆中的排序只保证了子节点的下次 执行时间要比父节点的下次执行时间要大,而叶子节点之间并不一定是顺序的)。
heap -》堆结构
1. 最小根堆
2. 最大根堆
存储数据结构是一个数组。
End!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)