写点什么

ScheduledThreadPoolExecutor

作者:周杰伦本人
  • 2022 年 6 月 14 日
  • 本文字数:1079 字

    阅读完需:约 4 分钟

ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务。


DelayQueue 是一个无界队列,所以 ThreadPoolExecutor 的 maximumPoolSize 在 ScheduledThreadPoolExecutor 中没有什么意义


ScheduledThreadPoolExecutor 的执行主要分为两大部分。1)当调用 ScheduledThreadPoolExecutor 的 scheduleAtFixedRate()方法或者 scheduleWithFixedDelay()方法时,会向 ScheduledThreadPoolExecutor 的 DelayQueue 添加一个实现了 RunnableScheduledFutur 接口的 ScheduledFutureTask。2)线程池中的线程从 DelayQueue 中获取 ScheduledFutureTask,然后执行任务。


ScheduledThreadPoolExecutor 为了实现周期性的执行任务,对 ThreadPoolExecutor 做了如下的修改。·使用 DelayQueue 作为任务队列。·获取任务的方式不同。·执行周期任务后,增加了额外的处理。


ScheduledThreadPoolExecutor 会把待调度的任务(ScheduledFutureTask)放到一个 DelayQueue 中。


ScheduledFutureTask 主要包含 3 个成员变量,如下。


  • long 型成员变量 time,表示这个任务将要被执行的具体时间。

  • long 型成员变量 sequenceNumber,表示这个任务被添加到 ScheduledThreadPoolExecutor 中的序号。

  • long 型成员变量 period,表示任务执行的间隔周期。


DelayQueue 封装了一个 PriorityQueue,这个 PriorityQueue 会对队列中的 ScheduledFutureTask 进行排序。排序时,time 小的排在前面(时间早的任务将被先执行)。如果两个 ScheduledFutureTask 的 time 相同,就比较 sequenceNumber,sequenceNumber 小的排在前面(也就是说,如果两个任务的执行时间相同,那么先提交的任务将被先执行)。


1)线程 1 从 DelayQueue 中获取已到期的 ScheduledFutureTask(DelayQueue.take())。到期任务是指 ScheduledFutureTask 的 time 大于等于当前时间。


2)线程 1 执行这个 ScheduledFutureTask。


3)线程 1 修改 ScheduledFutureTask 的 time 变量为下次将要被执行的时间。


4)线程 1 把这个修改 time 之后的 ScheduledFutureTask 放回 DelayQueue 中(DelayQueue.add())。


1)获取 Lock。2)获取周期任务。·如果 PriorityQueue 为空,当前线程到 Condition 中等待;否则执行下面的 2.2。·如果 PriorityQueue 的头元素的 time 时间比当前时间大,到 Condition 中等待到 time 时间;否则执行下面的 2.3。·获取 PriorityQueue 的头元素(2.3.1);如果 PriorityQueue 不为空,则唤醒在 Condition 中等待的所有线程(2.3.2)。3)释放 Lock。


1)获取 Lock。2)添加任务。·向 PriorityQueue 添加任务。·如果在上面 2.1 中添加的任务是 PriorityQueue 的头元素,唤醒在 Condition 中等待的所有线程。3)释放 Lock。

发布于: 刚刚阅读数: 5
用户头像

还未添加个人签名 2020.02.29 加入

还未添加个人简介

评论

发布
暂无评论
ScheduledThreadPoolExecutor_6月月更_周杰伦本人_InfoQ写作社区