Java Timer使用介绍

java.util包下提供了对定时任务的支持,涉及2个类:

  1. Timer:定时器类
  2. TimerTask:任务抽象类
使用该定时任务我们需要继承TimerTask抽象类,覆盖run方法编写任务执行代码,并利用Timer定时器对TimerTask进行调度 。
编写一个任务:
TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println(DateUtil.formatNow() + " " + Thread.currentThread().getName() + " task run ");}};接着使用Timer对TimerTask进行调度,Timer提供了多种方法,可分为一次性任务和可重复执行任务 。
一、一次性任务一次性任务是指Timer执行一次之后,该任务后续不再执行 。
一次性任务包括2个方法,如下:
  1. void schedule(TimerTask task, long delay):延迟delay毫秒后执行一次task
  2. void schedule(TimerTask task, Date time):在指定时间time执行一次task,如果time过期,将会立即执行
二、可重复执行任务可重复执行任务是指,任务允许按照设定的规则重复执行 。
可重复执行任务共有4个方法,分为 固定延时 schedule 和 固定速率 scheduleAtFixedRate:
  1. void schedule(TimerTask task, long delay, long period):延迟delay毫秒后执行task,之后每隔period毫秒执行一次task
  2. void schedule(TimerTask task, Date firstTime, long period):在指定时间time执行一次task,之后每隔period毫秒执行一次task
  3. void scheduleAtFixedRate(TimerTask task, long delay, long period):延迟delay毫秒后执行task,之后每隔period毫秒执行一次task
  4. void scheduleAtFixedRate(TimerTask task, Date firstTime, long period):在指定时间time执行一次task,之后每隔period毫秒执行一次task
示例1:schedule方法 , 延迟delay毫秒后执行task,之后每隔period毫秒执行一次task
System.out.println("启动于:" + DateUtil.formatNow());Timer timer = new Timer("timer");timer.schedule(task, 1000, 2000);输出:
启动于:2022-10-31 10:05:152022-10-31 10:05:16 timer task run2022-10-31 10:05:18 timer task run2022-10-31 10:05:20 timer task run示例2:schedule在指定时间time执行一次task,之后每隔period毫秒执行一次task
System.out.println("启动于:" + DateUtil.formatNow());Timer timer = new Timer("timer");timer.schedule(task, DateUtil.parse("2022-10-31 10:07:00", DateUtil.YYYY_MM_DD_HH24_MM_SS), 2000);输出:
启动于:2022-10-31 10:06:392022-10-31 10:07:00 timer task run2022-10-31 10:07:02 timer task run2022-10-31 10:07:04 timer task run 固定延时 schedule 和 固定速率 scheduleAtFixedRate 在正常情况下看起来功能基本是一致的,区别在于当任务耗时超出执行时间间隔period , 后续任务被延误时 , schedule和scheduleAtFixedRate的处理方式不同,后面介绍 。
三、固定延时和固定速率区别(重点)1. 介绍由于Timer内部仅维护一个线程来执行所有任务,所以当前一个任务耗时过长,可能会导致后一个任务的执行被延误 。
出现任务延误的情况下,固定延时 schedule和 固定速率 scheduleAtFixedRate 的区别就在于,schedule会顺延,而scheduleAtFixedRate会把延误任务立马补上 。
在网上看到几个非常恰当的例子,贴上来加深理解 。
例1:
暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业 。
老师要求学生暑假每天写2页,30天后完成作业 。
这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业 。任务被拖延了 。
这时候两个学生采取的策略就不同了:
schedule重新安排了任务时间,旅游回来的第一天做第11天的任务,第二天做第12天的任务,最后完成任务花了35天 。
【Java Timer使用介绍】scheduleAtFixedRate是个守时的学生 , 她总想按时完成老师的任务,于是在旅游回来的第一天把之前5天欠下的任务以及第16天当天的任务全部完成了,之后还是按照老师的原安排完成作业 , 最后完成任务花了30天 。
例2:
固定速率就好比你今天加班到很晚,但是到了第二天还必须准点到公司上班,如果你一不小心加班到了第二天早上 9 点,你就连休息的时间都没有了 。
而固定时延的意思是你必须睡够 8 个小时再过来上班,如果你加班到凌晨 6 点,那就可以下午过来上班了 。
固定速率强调准点 , 固定时延强调间隔 。

推荐阅读