阅读(1003) (5)

鸿蒙OS Timer

2022-06-16 16:30:19 更新

Timer

java.lang.Object

|---java.util.Timer

public class Timer
extends Object

线程调度任务以供将来在后台线程中执行的工具。 任务可以安排为一次性执行,或定期重复执行。

对应于每个 Timer 对象的是单个后台线程,用于按顺序执行所有计时器的任务。 定时器任务应该很快完成。 如果一个定时器任务花费了过多的时间来完成,它就会“占用”定时器的任务执行线程。 反过来,这可以延迟后续任务的执行,这些任务可能会在(如果)有问题的任务最终完成时“聚集”并快速连续执行。

在对 Timer 对象的最后一个实时引用消失并且所有未完成的任务都已完成执行后,计时器的任务执行线程优雅地终止(并成为垃圾回收的对象)。 但是,这可能需要任意长的时间才能发生。 默认情况下,任务执行线程不作为守护线程运行,因此它能够防止应用程序终止。 如果调用者想要快速终止定时器的任务执行线程,调用者应该调用定时器的取消方法。

如果计时器的任务执行线程意外终止,例如,因为调用了它的 stop 方法,那么任何进一步尝试在计时器上安排任务都将导致 IllegalStateException,就像调用了计时器的取消方法一样。

这个类是线程安全的:多个线程可以共享一个 Timer 对象而不需要外部同步。

此类不提供实时保证:它使用 Object.wait(long) 方法安排任务。

Java 5.0 引入了 java.util.concurrent 包,其中的并发实用程序之一是 ScheduledThreadPoolExecutor,它是一个线程池,用于以给定的速率或延迟重复执行任务。 它实际上是 Timer/TimerTask 组合的更通用替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类化 TimerTask(只需实现 Runnable)。 使用一个线程配置 ScheduledThreadPoolExecutor 使其等效于 Timer。

实施说明:此类可扩展到大量并发计划任务(数千个应该没有问题)。 在内部,它使用二进制堆来表示其任务队列,因此调度任务的成本为 O(log n),其中 n 是并发调度的任务数。

实现说明:所有构造函数都启动一个计时器线程。

构造函数摘要

构造函数 描述
Timer() 创建一个新的计时器。
Timer(boolean isDaemon) 创建一个新的计时器,其关联线程可以指定给 Thread#setDaemon。
Timer(String name) 创建一个新的计时器,其关联线程具有指定的名称。
Timer(String name, boolean isDaemon) 创建一个新的计时器,其关联线程具有指定的名称,并且可以指定给 Thread#setDaemon。

方法总结

修饰符和类型 方法 描述
void cancel() 终止此计时器,丢弃任何当前计划的任务。
int purge() 从此计时器的任务队列中删除所有已取消的任务。
void schedule(TimerTask task, long delay) 安排指定任务在指定延迟后执行。
void schedule(TimerTask task, long delay, long period) 安排指定任务以重复固定延迟执行,在指定延迟后开始。
void schedule(TimerTask task, Date time) 安排指定任务在指定时间执行。
void schedule(TimerTask task, Date firstTime, long period) 从指定时间开始,安排指定任务以重复固定延迟执行。
void scheduleAtFixedRate(TimerTask task, long delay, long period) 安排指定任务以重复固定速率执行,在指定延迟后开始。
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 从指定时间开始,安排指定任务以重复固定速率执行。
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

构造函数详细信息

Timer

public Timer()

创建一个新的计时器。 关联的线程没有 Thread#setDaemon。

Timer

public Timer(boolean isDaemon)

创建一个新的计时器,其关联线程可以指定给 Thread#setDaemon。 如果计时器将用于安排重复的“维护活动”,则调用守护线程,只要应用程序正在运行,就必须执行该活动,但不应延长应用程序的生命周期。

参数:

参数名称 参数描述
isDaemon 如果关联的线程应该作为守护进程运行,则为 true。

Timer

public Timer(String name)

创建一个新的计时器,其关联线程具有指定的名称。 关联的线程没有 Thread#setDaemon。

参数:

参数名称 参数描述
name 关联线程的名称

Throws:

Throw名称 Throw描述
NullPointerException 如果 name 为空

Timer

public Timer(String name, boolean isDaemon)

创建一个新的计时器,其关联线程具有指定的名称,并且可以指定给 Thread#setDaemon。

参数:

参数名称 参数描述
name 关联线程的名称
isDaemon 如果关联的线程应该作为守护进程运行,则为 true

Throws:

Throw名称 Throw描述
NullPointerException 如果 name 为空

方法详情

schedule

public void schedule(TimerTask task, long delay)

安排指定任务在指定延迟后执行。

参数:

参数名称 参数描述
task 要安排的任务。
delay 任务执行前的延迟毫秒数。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果延迟为负,或延迟 + System.currentTimeMillis() 为负。
IllegalStateException 如果任务已被安排或取消,定时器被取消,或定时器线程终止。
NullPointerException 如果任务为空

schedule

public void schedule(TimerTask task, Date time)

安排指定任务在指定时间执行。 如果时间是过去,则安排任务立即执行。

参数:

参数名称 参数描述
task 要安排的任务。
time 执行任务的时间。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 time.getTime() 是负数。
IllegalStateException 如果任务已被安排或取消,定时器被取消,或定时器线程终止。
NullPointerException 如果任务或时间为空

schedule

public void schedule(TimerTask task, long delay, long period)

安排指定任务以重复固定延迟执行,在指定延迟后开始。 随后的执行以大约固定的时间间隔进行,间隔指定的时间段。

在固定延迟执行中,每次执行都是相对于前一次执行的实际执行时间安排的。 如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则后续执行也会延迟。 从长远来看,执行频率一般会略低于指定周期的倒数(假设系统时钟底层 Object.wait(long) 是准确的)。

固定延迟执行适用于需要“顺利”的重复活动。 换句话说,它适用于在短期内保持频率准确比在长期内更重要的活动。 这包括大多数动画任务,例如定期闪烁光标。 它还包括响应人工输入执行常规活动的任务,例如只要按住一个键就自动重复一个字符。

参数:

参数名称 参数描述
task 要安排的任务。
delay 任务执行前的延迟毫秒数。
period 连续任务执行之间的时间(以毫秒为单位)。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果延迟 < 0,或延迟 + System.currentTimeMillis() < 0,或周期 <= 0
IllegalStateException 如果任务已被安排或取消,定时器被取消,或定时器线程终止。
NullPointerException 如果任务为空

schedule

public void schedule(TimerTask task, Date firstTime, long period)

从指定时间开始,安排指定任务以重复固定延迟执行。 随后的执行以大约固定的时间间隔进行,间隔指定的时间段。

在固定延迟执行中,每次执行都是相对于前一次执行的实际执行时间安排的。 如果由于任何原因(例如垃圾收集或其他后台活动)延迟执行,则后续执行也会延迟。 从长远来看,执行频率一般会略低于指定周期的倒数(假设系统时钟底层 Object.wait(long) 是准确的)。 作为上述的结果,如果预定的第一次是过去的,则预定立即执行。

固定延迟执行适用于需要“顺利”的重复活动。 换句话说,它适用于在短期内保持频率准确比在长期内更重要的活动。 这包括大多数动画任务,例如定期闪烁光标。 它还包括响应人工输入执行常规活动的任务,例如只要按住一个键就自动重复一个字符。

参数:

参数名称 参数描述
task 要安排的任务。
firstTime 第一次执行哪个任务。
period 连续任务执行之间的时间(以毫秒为单位)。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 firstTime.getTime() < 0,或 period <= 0
IllegalStateException 如果任务已被安排或取消,定时器被取消,或定时器线程终止。
NullPointerException 如果 task 或 firstTime 为 null

scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task, long delay, long period)

安排指定任务以重复固定速率执行,在指定延迟后开始。 随后的执行以大约固定的时间间隔进行,间隔指定的时间段。

在固定速率执行中,每次执行都是相对于初始执行的计划执行时间安排的。 如果由于任何原因(例如垃圾收集或其他后台活动)延迟了执行,则会快速连续发生两次或更多执行以“赶上”。 从长远来看,执行频率将恰好是指定周期的倒数(假设 Object.wait(long) 底层的系统时钟是准确的)。

固定速率执行适用于对绝对时间敏感的重复活动,例如每小时整点响铃,或每天在特定时间运行定期维护。 它也适用于执行固定执行次数的总时间很重要的重复活动,例如每秒滴答一次、持续 10 秒的倒计时计时器。 最后,固定速率执行适用于调度多个必须彼此保持同步的重复计时器任务。

参数:

参数名称 参数描述
task 要安排的任务。
delay 任务执行前的延迟毫秒数。
period 连续任务执行之间的时间(以毫秒为单位)。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果延迟 < 0,或延迟 + System.currentTimeMillis() < 0,或周期 <= 0
IllegalStateException if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
NullPointerException if task is null

scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

从指定时间开始,安排指定任务以重复固定速率执行。 随后的执行以大约固定的时间间隔进行,间隔指定的时间段。

在固定速率执行中,每次执行都是相对于初始执行的计划执行时间安排的。 如果由于任何原因(例如垃圾收集或其他后台活动)延迟了执行,则会快速连续发生两次或更多执行以“赶上”。 从长远来看,执行频率将恰好是指定周期的倒数(假设 Object.wait(long) 底层的系统时钟是准确的)。 由于上述原因,如果计划的第一次是在过去,那么任何“错过”的执行都将被安排立即“赶上”执行。

固定速率执行适用于对绝对时间敏感的重复活动,例如每小时整点响铃,或每天在特定时间运行定期维护。 它也适用于执行固定执行次数的总时间很重要的重复活动,例如每秒滴答一次、持续 10 秒的倒计时计时器。 最后,固定速率执行适用于调度多个必须彼此保持同步的重复计时器任务。

参数:

参数名称 参数描述
task 要安排的任务。
firstTime 第一次执行哪个任务。
period 连续任务执行之间的时间(以毫秒为单位)。

Throws:

Throw名称 Throw描述
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 是取消的任务数。

请注意,允许在此计时器上安排的任务中调用此方法。

返回:

从队列中删除的任务数。