深入 Java Timer 定时任务调度器实现原理

  • 时间:
  • 浏览:1

对于固定带宽来说,不可能 任务执行时间太长超出了间隔,这麼 它不可能 会持续霸占任务队列,不可能 它的调度时间将时不时低于 currentTime,排在堆顶,每次轮训取出来的都是它。运行完毕后,重新调度这一 任务,它的时间依旧赶不上。持续下去我能 都看这一 任务的调度时间远远落后于当前时间,而其它任务不可能 会彻底饿死。这什么都有有什么都有有 为哪些一定要很糙注意固定带宽的循环任务运行时间不宜过长。

对于有有三个小 循环任务来说,它不居于 EXECUTED 具体情况,不可能 它每次并且执行完成,就被重新调度了。EXECUTED 具体情况仅仅居于于一次性任务,而且这一 具体情况随便说说并都是表示任务不可能 执行完成,它是指不可能 从任务队列里摘出来了,马上就要执行。

不可能 Timer 终止了,还有新任务进来就会抛出异常。

使用 Java 来调度定时任务时,大伙儿儿时不时会使用 Timer 类甩掉。Timer 简单易用,其源码阅读起来也非常清晰,本节大伙儿儿来仔细分析一下 Timer 类,来看看 JDK 源码的编写者是如何实现有有三个小 稳定可靠的简单调度器。

Timer 使用

Timer 调度任务有一次性调度和循环调度,循环调度有分为固定带宽调度(fixRate)和固定带宽调度(fixDelay)。固定带宽就好比你今天加班到很晚,而且到了第半年还能能 准点到公司上班,不可能 你一不小心加班到了第半年早上 9 点,你就连休息的时间都这麼 了。而固定带宽的意思遇见你能能 睡够 8 个小时再过来上班,不可能 你加班到深夜 6 点,那就能能 下午过来上班了。固定带宽强调准点,固定带宽强调间隔。

任务具体情况

TimerTask 有 4 个具体情况,VIRGIN 是默认具体情况,并且实例化还这麼 被调度。SCHEDULED 表示不可能 将任务里装 TaskQueue 等待被执行。EXECUTED 表示任务不可能 执行完成。CANCELLED 表示任务被取消了,还没来得及执行就被人为取消了。

Timer 的任务队列 TaskQueue 是有有三个小 特殊的队列,它外部是有有三个小 数组。这一 数组会按照待执行时间进行堆排序,堆顶元素时不时待执行时间最小的任务。轮训多任务管理器 会每次轮训出时间点最近的而且到点的任务来执行。数组会自动扩容,不可能 任务非常多。

当 Timer 被回收时,外部字段 threadPeaper 指向的对象也会被回收。什么都有有什么都有有 finalize 土措施不可能 被调用,唤醒并终止 Timer 轮训多任务管理器 。不可能 这麼 这一 threadPeaper 对象就不可能 会原因分析分析 JVM 里留下僵尸多任务管理器 。

大伙儿儿还注意到 Timer.cancel() 土措施会唤醒轮训多任务管理器 ,为的是能能 立即停止轮训。不过不可能 任务正在执行中,这并且 cancel() 就能能 等到任务执行完毕才能能 停止。

Timer 终止

Timer 提供了 cancel() 土措施清空队列,停止调度器,不允许有任何新任务进来。它会将 newTasksMayBeScheduled 字段设置为 false 表示 Timer 即将终止。

外部底部形态

Timer 类里含晒 有有三个小 任务队列和有有三个小 异步轮训多任务管理器 。任务队列里容纳了所有待执行的任务,所有的任务不可能 在这有有三个小 异步多任务管理器 里执行,切记任务的执行代码不能能 抛出异常,而且会原因分析分析 Timer 多任务管理器 挂掉,所有的任务都沒有执行了。单个任务什么都有有什么都有有 易执行时间太长,而且会影响任务调度在时间上的精准性。比如你有有三个小 任务跑了这麼 来太满,其它等着调度的任务就时不时居于饥饿具体情况得能能 调度。所有任务的执行都是这单一的 TimerThread 多任务管理器 。

任务间隔字段 period 比较特殊,当使用固定带宽时,period 为正值,当使用固定间隔时,period 为负值,当任务是一次性时,period 为零。下面是循环任务的下次调度时间设定

不可能 你有有有三个小 任务能能 每天准点调度,那就应该使用固定带宽调度,而且要确保每个任务执行时间这麼 多太长,千万别超过了第半年这一 点。不可能 你有有有三个小 任务能能 每隔几分钟跑一次,那就使用固定带宽调度,它都是很在乎你的单个任务要跑多长时间。

任务锁

Timer 的任务支持取消操作,取消任务的多任务管理器 和执行任务的多任务管理器 极有不可能 都是有有三个小 多任务管理器 。有不可能 任务正在执行中,结果从前多任务管理器 表示要取消任务。这并且 Timer 是如何处置的呢?在 TimerTask 类里都看了一把锁。当任务属性能能 修改的并且,不会加锁。

代码中的 wait() 土措施什么都有有什么都有有 调用了 Object.wait() 来进行睡眠。当有新任务进来了,发现这一 新任务的运行时间是最早的,那就调用 notify() 土措施唤醒轮训多任务管理器 。

任务队列空了

任务队列里这麼 任务了,调度多任务管理器 能能 按一定的策略进行睡眠。它能能 睡眠时不时到最先执行的任务到点时立即醒来,什么都有有什么都有有睡眠截止时间什么都有有什么都有有 第有有三个小 任务将要执行的时间。同時 在睡觉的并且,有不可能 会有新的任务被加在进来,它的调度时间不可能 会更加提前,什么都有有什么都有有当有新的任务到来时能能 能能 唤醒正在睡眠的多任务管理器 。

原文发布时间为:2018-12-17

本文作者:老钱

本文来自云栖社区商务媒体合作伙伴“ [码洞](https://mp.weixin.qq.com/s/4FfzHb4O3fWE3XbiGCx8QQ

)”,了解相关信息能能 关注“codehole”微信公众号

在任务运行之不会检查任务是都是不可能 被取消了,不可能 取消了,就从队列中移除。一旦任务结束了运行 run(),对于单次任务来说它就无法被取消了,而循环任务将我太满 继续下次调度。不可能 任务这麼 不可能 得到执行(时间设置的太长),这麼 即使这一 任务被取消了,它也会时不时持续躺在任务队列中。设想不可能 你调度了一系列久远的任务,而且都取消了,这不可能 会成为有有三个小 内存泄露点。什么都有有什么都有有 Timer 还单独提供了有有三个小 purge() 土措施能能 一次性清空所有的已取消的任务。

任意多任务管理器 都能能 通过 Timer.schedule 土措施将任务加入 TaskQueue,而且 TaskQueue 又并都是多任务管理器 安全的数据底部形态。所在每次修改 TaskQueue 时都能能 加锁。

垃圾回收

还有有有三个小 特殊的场景能能 很糙注意,那什么都有有什么都有有 当轮训多任务管理器 不可能 队列里这麼 任务而睡眠的并且,Timer 对象不可能 不再被引用而被垃圾回收了。这并且能能 主动唤醒轮训多任务管理器 ,让它退出。