如果计时器任务的执行时间超过指定的时间间隔,会发生什么情况?

2022-09-02 00:46:49

使用时

Timer.schedule(TimerTask task, long delay, long period)

(即使用固定延迟执行),如果指定的方法花费的时间比完成时间长,会发生什么情况?是否有可能因此而运行两个并发线程?如果是这样,有没有办法避免它?TimerTaskrun()periodTimerTask


答案 1

Timer的文档说了以下内容:

计时器任务应快速完成。如果计时器任务需要过多的时间才能完成,则会“占用”计时器的任务执行线程。反过来,这可能会延迟后续任务的执行,当(以及如果)违规任务最终完成时,这些任务可能会“堆积起来”并快速连续执行。

也就是说,并发线程将不会运行。任务将累积到队列中。这可能合适,也可能不合适(更有可能,不合适)。TimerTask


答案 2

Timer并且不能很好地处理这种情况。如果你想更好地处理它,那么不要使用这些类。TimerTask

java.util.concurrent.ScheduledExecutorService 提供了两种调度方法,scheduleAtFixedRatescheduledWithFixedDelay,它们控制任务“堆积”时发生的情况。

scheduleAtFixedRate:

创建并执行一个周期性操作,该操作在给定的初始延迟后首先启用,随后在给定的时间段内启用;也就是说,执行将在初始延迟之后开始,然后是初始延迟+周期,然后是初始延迟 + 2 *周期,依此类推。如果任务的任何执行遇到异常,则禁止后续执行。否则,任务将仅通过取消或终止执行程序而终止。如果执行此任务所需的时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。

scheduleWithFixedDelay:

创建并执行一个定期操作,该操作在给定的初始延迟之后首先启用,然后在一个执行终止和下一个执行开始之间的给定延迟下一个执行期间启用。如果任务的任何执行遇到异常,则禁止后续执行。否则,任务将仅通过取消或终止执行程序而终止。

您可以使用工厂类创建实例。ScheduledExecutorServiceExecutors