Java中定时任务的6种实现方式,你知道几种?

06-13 1240阅读

固定速率执行

在指定的延迟时间开始执行定时任务,定时任务按照固定的速率进行执行。比如:延迟2秒执行,固定速率为1秒。

Java中定时任务的6种实现方式,你知道几种?
(图片来源网络,侵删)

public class FixedRateDemo {

public static void main(String[] args) {

Timer timer = new Timer();

timer.scheduleAtFixedRate(new DoSomethingTimerTask(“FixedRateDemo”),2000L,1000L);

}

}

执行程序,会发现2秒之后开始每隔1秒执行一次。

此时,你是否疑惑schedule与scheduleAtFixedRate效果一样,为什么提供两个方法,它们有什么区别?

schedule与scheduleAtFixedRate区别

在了解schedule与scheduleAtFixedRate方法的区别之前,先看看它们的相同点:

  • 任务执行未超时,下次执行时间 = 上次执行开始时间 + period;

  • 任务执行超时,下次执行时间 = 上次执行结束时间;

在任务执行未超时时,它们都是上次执行时间加上间隔时间,来执行下一次任务。而执行超时时,都是立马执行。

它们的不同点在于侧重点不同,schedule方法侧重保持间隔时间的稳定,而scheduleAtFixedRate方法更加侧重于保持执行频率的稳定。

schedule侧重保持间隔时间的稳定

schedule方法会因为前一个任务的延迟而导致其后面的定时任务延时。计算公式为scheduledExecutionTime(第n+1次) = realExecutionTime(第n次) + periodTime。

也就是说如果第n次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做时隔等待,立即执行第n+1次task。

而接下来的第n+2次task的scheduledExecutionTime(第n+2次)就随着变成了realExecutionTime(第n+1次)+periodTime。这个方法更注重保持间隔时间的稳定。

scheduleAtFixedRate保持执行频率的稳定

scheduleAtFixedRate在反复执行一个task的计划时,每一次执行这个task的计划执行时间在最初就被定下来了,也就是scheduledExecutionTime(第n次)=firstExecuteTime +n*periodTime。

如果第n次执行task时,由于某种原因这次执行时间过长,执行完后的systemCurrentTime>= scheduledExecutionTime(第n+1次),则此时不做period间隔等待,立即执行第n+1次task。

接下来的第n+2次的task的scheduledExecutionTime(第n+2次)依然还是firstExecuteTime+(n+2)*periodTime这在第一次执行task就定下来了。说白了,这个方法更注重保持执行频率的稳定。

如果用一句话来描述任务执行超时之后schedule和scheduleAtFixedRate的区别就是:schedule的策略是错过了就错过了,后续按照新的节奏来走;scheduleAtFixedRate的策略是如果错过了,就努力追上原来的节奏(制定好的节奏)。

Timer的缺陷

Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务)。但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。

其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,它会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。

JDK自带ScheduledExecutorService


ScheduledExecutorService是JAVA 1.5后新增的

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]