Java 超详细解释Timer定时器

本文详细解析了Java中的Timer类,包括其继承结构、主要方法及其实现定时任务的多种方式。通过示例代码展示了如何使用schedule方法的不同参数组合来实现未来执行、提前执行、延时执行和不延时执行。同时对比了schedule和scheduleAtFixedRate方法的执行特点,强调了schedule不具有追赶执行性,而scheduleAtFixedRate具有此特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先来看看此类在JavaSE文档中对Timer类的8点解释:

1.线程的工具,用于在后台线程中安排将来执行的任务。可以将任务安排为一次性执行,或者以固定间隔重复执行。

2.对应于每个Timer对象的是一个后台线程,用于按顺序执行所有计时器的任务。

3.计时器任务应该快速完成。

4.如果计时器任务花费过多时间来完成,它会“占用”计时器的任务执行线程。反过来,这可以延迟后续任务的执行,后续任务可以在紧急任务最终完成时(以及如果)快速连续地“聚集”并执行。

5.默认情况下,任务执行线程不作为守护程序线程运行,因此它能够阻止应用程序终止。如果调用者想要快速终止计时器的任务执行线程,则调用者应该调用计时器的cancel方法。

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

7.此类是线程安全的:多个线程可以共享单个 Timer对象,而无需外部同步。

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

继承结构
在这里插入图片描述


方法:

在这里插入图片描述
发现方法 schedule占Timer类的大部分,从schedule方法中可以看出执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类。

下面我将对schedule进行了解:

此方法有如下几种执行情况

  • 未来执行
  • 提前执行
  • 延时执行
  • 不延时执行

1.方法schedule(TimerTask task,Date time)

作用:该方法的作用是在指定的日期执行一次某一任务

未来执行:(执行的时间比当前的时间晚)
在这里插入图片描述
在这里插入图片描述

任务虽然运行结束,但进程没有被销毁。此问题需要我们来看看创建Timer对象的源码:
在这里插入图片描述
该构造方法调用的是如下有参构造方法:
在这里插入图片描述
由此可知,创建了一个Timer对象就是启动了一个新线程,此线程不是守护线程,它是一直运行的。正如文档对它的解释。

那么如何将它改为守护线程呢?
很简单,修改如下语句:
在这里插入图片描述
看看运行结果:

在这里插入图片描述
此时任务执行完毕,线程也被销毁了。

.

提前执行(计划的时间比当前时间要早)
作用:如果执行任务的时间早于当前时间,则立即执行task任务。

往main中添加如下语句:
在这里插入图片描述
执行结果:
在这里插入图片描述

延时执行(多个TimerTask任务)
Timer是允许有多个TimerTask任务的。

在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述
TimerTask是以队列的方式一个一个顺序执行的,所以执行的时间可能会和预期的不一致,为什么这么说呢,因为每个TimerTask的执行时间有长短,前面执行时间长会拖延后面的执行时间。

2.方法 schedule​(TimerTask task, Date firstTime, long period)

作用:过了指定日期之后,按指定的间隔周期性地无限循环地执行某一任务。

未来执行(计划时间要比当前时间晚)
修改前面代码的两处地方:

在这里插入图片描述
运行结果:
在这里插入图片描述
每4秒无限期重复执行TimerTask任务。

提前运行(计划时间要比当前时间早)
如果计划时间早于当前时间,则立即执行task任务。

在这里插入图片描述在这里插入图片描述
此时task任务立即执行了。

延时执行
修改MyTask类中run()方法:

在这里插入图片描述
执行效果:
在这里插入图片描述
3.方法schedule​(TimerTask task, long delay)

作用:在指定的延迟后安排指定的毫秒数后任务执行。

延时执行
在这里插入图片描述

任务task的执行被延迟了4秒。
在这里插入图片描述

4.方法schedule​(TimerTask task, long delay, long period)

作用:在指定的延迟之后开始,为重复的固定延迟执行安排指定的任务。

延时执行
修改上面代码:
在这里插入图片描述

运行效果:
在这里插入图片描述
效果为:无限循环执行TimerTask中的任务。
此测试效果证明凡是使用方法中带有period参数的,都是无限循环执行TimerTask中的任务的。

5.方法scheduleAtFixedRate​(TimerTask task, Date firstTime, long period)

作用:从指定的时间开始,为重复的固定速率执行安排指定的任务。

下面对方法schedule与scheduleAtFixedRate​进行对比:
1.都是按顺序执行的,不用考虑非线程安全的问题。
2.都是执行任务的时间被延时:
schedule: 下一次任务的执行时间参考上一次开始时的时间来计算。
scheduleAtFixedRate:下一次任务的执行时间参考上一次结束时的时间来计算。

使用schedule任务不延时执行

在这里插入图片描述
运行效果:
在这里插入图片描述
结果表明,在不延时的情况下,如果执行任务的时间没有延时,则下一次执行任务的时间是上一次任务的开始时间加上delay时间。

使用schedule任务延时执行
修改如下两处代码:

在这里插入图片描述
在这里插入图片描述
运行效果:
在这里插入图片描述
结果表明:在不延时的情况下,如果执行任务的时间被延时,则下一次执行任务的时间是上一次任务的结束时间为参考来计算。

使用scheduleAtFixedRate任务不延时执行
将上面的时间改回来,然后把schedule方法改为scheduleAtFixedRate:

运行效果:
在这里插入图片描述
结果表明,在不延时的情况下,如果执行任务的时间没有延时,则下一次执行任务的时间是上一次任务的开始时间加上delay时间。

下面的延迟任务情况就不做介绍了,和上面的操作一样,依次判断。

验证schedule方法不具有追赶执行性

在这里插入图片描述
运行效果:
在这里插入图片描述
从结果可以看出: 时间:2019-3-24 15:39:00 当前时间:2019-3-24 17:30:59之间的时间所对应的Task任务被取消了,schedule方法不具有追赶执行性。

将schedule方法改为scheduleAtFixedRate方法。
运行效果:
在这里插入图片描述
运行效果说明:scheduleAtFixedRate方法具有追赶执行性。

下面简单介绍下TimerTask中的方法:
在这里插入图片描述
cancel():将自身任务从任务队列中清除,其他任务不被影响。

而Timer中的cancel()方法:终止此计时器,丢弃当前计划的任何任务,而且进程会被销毁掉。不过有时并不一定会停止执行计划任务,而是正常执行,这是因为Timer类中的cancel()方法有时并没有争抢到queue锁,所以TimerTask类中的任务继续正常执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值