【Java】浅谈ScheduledThreadPoolExecutor
一,概述
ScheduledThreadPoolExecutor继承ThreadPoolExecutor,新增了定时、延时任务API,结合
【Java】DelayQueue-CSDN博客
线程池原理简谈_线程池懒加载-CSDN博客
两篇基础文章,本篇笔者简单看下ScheduledThreadPoolExecutor是如何实现定时、延时任务。
二,实现
延时任务
1,实现延迟任务,需要延时为key的优先级队列,看下ScheduledThreadPoolExecutor构造方法,
可以看到,其BlockQueue是DelayedWorkQueue,这是ScheduledThreadPoolExecutor静态内部类,
通过poll从队列中取值,当getDelay返回值 > 0,则不能执行此任务,这是延迟任务的判断依据。
接下来,跟进getDelay,看下RunnableScheduleFeturn唯一实现类
time保留了触发时间,这得从schedule方法说起
当前时间+delay即triggerTime,这很容易
上文说过,DelayQueue是一个优先级队列,那么加入队列,会对time进行插入排序,简单看下offer
找到队列中合适位置,插入,不赘述。
此处的queue是以最小堆结构实现,
最后,当满足延时条件后,执行run即可,
定时任务
scheduleAtFixedRate方法作为分析入口
将innitalDelay和period保存到ScheduledFuturnTask,并且outerTask保存一次sft,就是t本身
跟进Run方法
因为outerTask本身就是当前Task,也是一个延时任务,outerTask属于自己引用自己,
当任务run后,通过setNextRuntime设置下一次的触发时间,再重新入队即可
因此,定时任务本质是延时任务执行完毕后又将自己加入执行队列