每个Timer
对象对应一个用于按顺序执行所有计时器任务的单个后台线程。计时器任务应该快速完成。如果计时器任务花费过多时间来完成,它会“占用”计时器的任务执行线程。这反过来会延迟执行后续任务,当(如果)有问题的任务最终完成时,后续任务可能会“堆积”并快速连续执行。
当对Timer
对象的最后一个活动引用消失并且所有未完成的任务已经执行完成后,计时器的任务执行线程会优雅地终止(并成为垃圾回收的对象)。然而,这可能需要任意长的时间才能发生。默认情况下,任务执行线程不作为守护线程运行,因此它有可能阻止应用程序终止。如果调用者想要快速终止计时器的任务执行线程,调用者应该调用计时器的cancel
方法。
如果计时器的任务执行线程意外终止,例如,因为调用了其stop
方法,任何进一步尝试在计时器上安排任务都将导致IllegalStateException
,就好像调用了计时器的cancel
方法一样。
这个类是线程安全的:多个线程可以共享一个Timer
对象,而无需外部同步。
这个类不提供实时保证:它使用Object.wait(long)
方法来安排任务。
Java 5.0引入了java.util.concurrent
包,其中的一个并发工具是ScheduledThreadPoolExecutor
,它是一个用于按给定速率或延迟重复执行任务的线程池。它实际上是Timer
/TimerTask
组合的更多功能替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要对TimerTask
进行子类化(只需实现Runnable
)。将ScheduledThreadPoolExecutor
配置为一个线程等效于Timer
。
实现注意事项:这个类可以扩展到大量同时安排的任务(数千个不应该有问题)。在内部,它使用二叉堆来表示其任务队列,因此安排任务的成本为O(log n),其中n是同时安排的任务数。
实现注意事项:所有构造函数都会启动一个计时器线程。
- 自从:
- 1.3
- 参见:
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
cancel()
终止此计时器,丢弃当前所有已安排的任务。int
purge()
从此计时器的任务队列中删除所有已取消的任务。void
将指定的任务安排在指定延迟后执行。void
将指定的任务安排为重复的固定延迟执行,在指定延迟后开始。void
将指定的任务安排在指定时间执行。void
将指定的任务安排为重复的固定延迟执行,从指定时间开始。void
scheduleAtFixedRate
(TimerTask task, long delay, long period) 将指定的任务安排为重复的固定速率执行,在指定延迟后开始。void
scheduleAtFixedRate
(TimerTask task, Date firstTime, long period) 将指定的任务安排为重复的固定速率执行,从指定时间开始。
-
Constructor Details
-
Timer
public Timer()创建一个新的计时器。关联的线程不会作为守护线程运行。 -
Timer
public Timer(boolean isDaemon) 创建一个新的计时器,其关联的线程可以指定为作为守护线程运行。如果计时器将用于安排重复的“维护活动”,则需要调用守护线程,这些活动必须在应用程序运行时执行,但不应延长应用程序的生命周期。- 参数:
-
isDaemon
- 如果关联的线程应该作为守护线程运行。
-
Timer
创建一个新的计时器,其关联的线程具有指定的名称。关联的线程不会作为守护线程运行。- 参数:
-
name
- 关联线程的名称 - 抛出:
-
NullPointerException
- 如果name
为null - 自从:
- 1.5
-
Timer
创建一个新的计时器,其关联的线程具有指定的名称,并且可以指定为作为守护线程运行。- 参数:
-
name
- 关联线程的名称 -
isDaemon
- 如果关联的线程应该作为守护线程运行 - 抛出:
-
NullPointerException
- 如果name
为null - 自从:
- 1.5
-
-
Method Details
-
schedule
将指定的任务安排在指定延迟后执行。- 参数:
-
task
- 要安排的任务。 -
delay
- 任务执行前的延迟时间(毫秒)。 - 抛出:
-
IllegalArgumentException
- 如果delay
为负数,或delay + System.currentTimeMillis()
为负数。 -
IllegalStateException
- 如果任务已经被安排或取消,计时器已被取消,或计时器线程终止。 -
NullPointerException
- 如果task
为null
-
schedule
将指定的任务安排在指定时间执行。如果时间已经过去,任务将立即执行。- 参数:
-
task
- 要安排的任务。 -
time
- 任务执行的时间。 - 抛出:
-
IllegalArgumentException
- 如果time.getTime()
为负数。 -
IllegalStateException
- 如果任务已经被安排或取消,计时器已被取消,或计时器线程终止。 -
NullPointerException
- 如果task
或time
为null
-
schedule
将指定的任务安排为重复的固定延迟执行,在指定延迟后开始。后续执行将以大约固定间隔分隔。在固定延迟执行中,每次执行都相对于上一次执行的实际执行时间安排。如果由于任何原因(如垃圾回收或其他后台活动)导致执行延迟,后续执行也将延迟。从长远来看,执行频率通常略低于指定周期的倒数(假设
Object.wait(long)
下的系统时钟是准确的)。固定延迟执行适用于需要“平滑性”的重复活动。换句话说,适用于在短期内保持频率准确性更为重要的活动,而不是在长期内。这包括大多数动画任务,例如定期闪烁光标。它还包括对人类输入做出响应时执行常规活动的任务,例如在按住键时自动重复字符。
- 参数:
-
task
- 要安排的任务。 -
delay
- 任务执行前的延迟时间(毫秒)。 -
period
- 连续任务执行之间的时间间隔(毫秒)。 - 抛出:
-
IllegalArgumentException
- 如果delay < 0
,或delay + System.currentTimeMillis() < 0
,或period <= 0
-
IllegalStateException
- 如果任务已经被安排或取消,计时器已被取消,或计时器线程终止。 -
NullPointerException
- 如果task
为null
-
schedule
将指定的任务安排为重复的固定延迟执行,从指定时间开始。后续执行将以大约固定间隔分隔。在固定延迟执行中,每次执行都相对于上一次执行的实际执行时间安排。如果由于任何原因(如垃圾回收或其他后台活动)导致执行延迟,后续执行也将延迟。从长远来看,执行频率通常略低于指定周期的倒数(假设
Object.wait(long)
下的系统时钟是准确的)。由于上述原因,如果计划的第一次时间已经过去,它将立即执行。固定延迟执行适用于需要“平滑性”的重复活动。换句话说,适用于在短期内保持频率准确性更为重要的活动,而不是在长期内。这包括大多数动画任务,例如定期闪烁光标。它还包括对人类输入做出响应时执行常规活动的任务,例如在按住键时自动重复字符。
- 参数:
-
task
- 要被调度的任务。 -
firstTime
- 要执行任务的第一次时间。 -
period
- 连续任务执行之间的时间间隔(以毫秒为单位)。 - 抛出:
-
IllegalArgumentException
- 如果firstTime.getTime() < 0
,或者period <= 0
-
IllegalStateException
- 如果任务已经被调度或取消,定时器已被取消,或定时器线程已终止。 -
NullPointerException
- 如果task
或firstTime
为null
-
scheduleAtFixedRate
将指定的任务安排为重复的固定速率执行,在指定延迟后开始。后续执行大约以固定间隔进行,间隔为指定的时间段。在固定速率执行中,每次执行都相对于初始执行的计划执行时间安排。如果由于任何原因(如垃圾回收或其他后台活动)而延迟执行,将会出现两次或更多次的快速连续执行以“赶上”。从长远来看,执行的频率将完全是指定周期的倒数(假设底层
Object.wait(long)
的系统时钟是准确的)。固定速率执行适用于对绝对时间敏感的重复活动,例如每小时整点响铃,或每天特定时间运行计划维护。它也适用于执行固定数量的执行所需的总时间很重要的重复活动,例如每秒滴答一次十秒的倒计时器。最后,固定速率执行适用于安排多个重复的定时器任务,这些任务必须在彼此之间保持同步。
- 参数:
-
task
- 要被调度的任务。 -
delay
- 任务执行前的延迟时间(以毫秒为单位)。 -
period
- 连续任务执行之间的时间间隔(以毫秒为单位)。 - 抛出:
-
IllegalArgumentException
- 如果delay < 0
,或者delay + System.currentTimeMillis() < 0
,或者period <= 0
-
IllegalStateException
- 如果任务已经被调度或取消,定时器已被取消,或定时器线程已终止。 -
NullPointerException
- 如果task
为null
-
scheduleAtFixedRate
将指定的任务安排为重复的固定速率执行,从指定时间开始。后续执行大约以固定间隔进行,间隔为指定的时间段。在固定速率执行中,每次执行都相对于初始执行的计划执行时间安排。如果由于任何原因(如垃圾回收或其他后台活动)而延迟执行,将会出现两次或更多次的快速连续执行以“赶上”。从长远来看,执行的频率将完全是指定周期的倒数(假设底层
Object.wait(long)
的系统时钟是准确的)。由于上述原因,如果计划的第一次时间在过去,则任何“错过”的执行将被安排为立即“赶上”执行。固定速率执行适用于对绝对时间敏感的重复活动,例如每小时整点响铃,或每天特定时间运行计划维护。它也适用于执行固定数量的执行所需的总时间很重要的重复活动,例如每秒滴答一次十秒的倒计时器。最后,固定速率执行适用于安排多个重复的定时器任务,这些任务必须在彼此之间保持同步。
- 参数:
-
task
- 要被调度的任务。 -
firstTime
- 要执行任务的第一次时间。 -
period
- 连续任务执行之间的时间间隔(以毫秒为单位)。 - 抛出:
-
IllegalArgumentException
- 如果firstTime.getTime() < 0
或者period <= 0
-
IllegalStateException
- 如果任务已经被调度或取消,定时器已被取消,或定时器线程已终止。 -
NullPointerException
- 如果task
或firstTime
为null
-
cancel
public void cancel()终止此定时器,丢弃当前已计划的任何任务。不会干扰当前正在执行的任务(如果存在)。一旦定时器被终止,其执行线程将优雅地终止,不再可以在其上安排更多任务。请注意,从调用此方法的定时器任务的run方法中调用此方法绝对保证正在进行的任务执行是此定时器将执行的最后一个任务执行。
此方法可以重复调用;第二次及后续调用不会产生任何效果。
-
purge
public int purge()从此定时器的任务队列中删除所有已取消的任务。 调用此方法不会影响定时器的行为,但会从队列中消除对已取消任务的引用。如果这些任务没有外部引用,则它们将变得可供垃圾回收。大多数程序不需要调用此方法。它设计用于罕见的取消大量任务的应用程序。调用此方法会以时间换空间:方法的运行时间可能与n + c log n成正比,其中n是队列中的任务数,c是已取消任务的数量。
请注意,可以从安排在此定时器上的任务内调用此方法。
- 返回:
- 从队列中删除的任务数。
- 自版本:
- 1.5
-