Java多线程学习之定时器 Timer

定时 / 计划功能

定时 / 计划功能在移动开发领域使用较多,比如 Android 技术。定时计划任务功能在 Java 中主要使用的就是 Timer 对象,它在内部使用多线程的方式进行处理,所以它和线程技术还是有非常大的关联的。

定时器 Timer 的使用

Java多线程学习之定时器 Timer_第1张图片

在 JDK 库中 Timer 类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。Timer 类的方法列表如下所示:
构造方法

Java多线程学习之定时器 Timer_第2张图片

常用方法

Java多线程学习之定时器 Timer_第3张图片

Timer 类的主要作用就是设置计划任务,但封装任务的类却是 TimerTask 类,类结构如下:


Java多线程学习之定时器 Timer_第4张图片

方法如下:


Java多线程学习之定时器 Timer_第5张图片

执行计划任务的代码要放入 TimerTask 的子类中,因为 TimerTask 是一个抽象类。

方法 schedule(TimerTask task, Date time) 的测试

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

1.计划时间晚于当前时间:在未来执行的效果

Run1.java

Java多线程学习之定时器 Timer_第6张图片

运行结果

运行完了,但进程还未销毁,这是为什么呢?

分析
Timer 的无参构造方法会启动一个新线程,这个新启动的线程不是守护线程,它一直在运行。

修改 Timer 的构造方法,传入参数 true,表示设置该线程为守护线程

运行结果


可以看到主线程运行完毕,守护线程中的任务未执行线程就结束了。

2.计划时间早于当前时间:提前运行的效果

如果执行任务的时间早于当前时间,则立即执行 task 任务。

示例代码

Java多线程学习之定时器 Timer_第7张图片

运行结果

3.多个 TimerTask 任务及延时的测试

Timer 中允许有多个 TimerTask 任务
Run2.java

Java多线程学习之定时器 Timer_第8张图片

Java多线程学习之定时器 Timer_第9张图片

运行结果
Java多线程学习之定时器 Timer_第10张图片

Timer 是以队列的形式排队执行的,所以执行的时间可能和预期的时间不一致,因为前面的任务可能消耗时间较长,则后面的任务运行的时间也会被延迟。
Run2Later.java
Java多线程学习之定时器 Timer_第11张图片

Java多线程学习之定时器 Timer_第12张图片

运行结果

Java多线程学习之定时器 Timer_第13张图片

分析
由于 task1 需要用时 20 秒执行完任务,task1 开始的时间是 11:33:00,那么将要影响 task2 的计划任务执行的时间,task2 以此时间为基准,向后延迟 20 秒,task2 在 11:33:20执行任务。因为 Task 是被放入队列中的,得一个一个顺序运行。

方法 schedule(TimerTask task, Date firsttime, long period) 的测试

该方法的作用是在指定日期之后,按指定的间隔周期性地无限循环执行某一任务。

1.计划时间晚于当前时间:在未来执行的效果

Run.java

Java多线程学习之定时器 Timer_第14张图片

运行结果

Java多线程学习之定时器 Timer_第15张图片

从运行结果来看,每隔 4 秒运行一次 TimerTask 任务,并且是无限期地重复执行。

2.计划时间早于当前时间:提前运行的效果

如果执行任务的时间早于当前时间,则立即执行 task 任务。
示例代码

Java多线程学习之定时器 Timer_第16张图片

运行结果

Java多线程学习之定时器 Timer_第17张图片

3.任务执行时间被延迟

Run2_1.java

Java多线程学习之定时器 Timer_第18张图片

运行结果
Java多线程学习之定时器 Timer_第19张图片

任务被延迟但还是一个一个顺序运行。

4.TimerTask 类的 cancel() 方法

TimerTask 类中的 cancel() 方法是将自身从任务队列中清除,其他任务不受影响。
Run2.java

Java多线程学习之定时器 Timer_第20张图片

运行结果
Java多线程学习之定时器 Timer_第21张图片

TimerTaskA仅运行一次后被清除了。

5.Timer 类的 cancel() 方法

和 TimerTask 类中的 cancel() 方法清除自身不同,Timer 类中的 cancel() 方法的作用是将任务队列中的全部任务清空。
Run3.java

Java多线程学习之定时器 Timer_第22张图片

运行结果

TimerTaskA运行一次后所有任务都被移除。

6.Timer 的 cancel() 方法注意事项

Timer 中的 cancel() 方法有时并不一定会停止执行计划任务,而是正常执行。
Run4.java

Java多线程学习之定时器 Timer_第23张图片

运行结果
Java多线程学习之定时器 Timer_第24张图片

分析
任务并没有停止执行,这是因为Timer 中的 cancel() 方法有时并没有争抢到 queue 锁,所以 TimerTask 中的任务继续正常执行。

方法 schedule(TimerTask task, long delay) 的测试

该方法的作用是以执行 schedule(TimerTask task, long delay) 方法当前的时间为基准,在此基础上延迟指定的毫秒数后执行一次 TimerTask 任务。
Run.java

Java多线程学习之定时器 Timer_第25张图片

运行结果


任务 task 被延迟了 7 秒执行。

方法 schedule(TimerTask task, long delay, long period) 的测试

该方法的作用是以执行 schedule(TimerTask task, long delay, long period) 方法当前的时间为基准,在此基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行某一任务。

Run.java

Java多线程学习之定时器 Timer_第26张图片

运行结果

Java多线程学习之定时器 Timer_第27张图片

凡是使用方法中带有 period 参数的,都是无限循环执行 TimerTask 中的任务。

方法 scheduleAtFixedRate(TimerTask timer, Date firstTime, long period)

Java多线程学习之定时器 Timer_第28张图片
1.测试 schedule 方法不延时

Run1.java

Java多线程学习之定时器 Timer_第29张图片

Java多线程学习之定时器 Timer_第30张图片

运行结果

Java多线程学习之定时器 Timer_第31张图片

如果执行任务的时间没有被延迟,则下一次执行时间是上一次任务的开始时间加上 delay 时间。

2.测试 schedule 方法延时

Run2.java

Java多线程学习之定时器 Timer_第32张图片

运行结果

Java多线程学习之定时器 Timer_第33张图片

如果执行任务的时间被延迟,那么下一次任务的执行时间以上一次任务“结束”的时间为参考来计算。

3.测试 scheduleAtFixedRate 方法不延时

Run3.java

Java多线程学习之定时器 Timer_第34张图片

运行结果
Java多线程学习之定时器 Timer_第35张图片

如果执行任务的时间没有被延迟,则下一次执行时间是上一次任务的开始时间加上 delay 时间。

4.测试 scheduleAtFixedRate 方法延时

Run4.java

Java多线程学习之定时器 Timer_第36张图片


运行结果
Java多线程学习之定时器 Timer_第37张图片

如果执行任务的时间被延迟,那么下一次任务的执行时间以上一次任务“结束”的时间为参考来计算。

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

Run5.java

Java多线程学习之定时器 Timer_第38张图片


运行结果
Java多线程学习之定时器 Timer_第39张图片

时间 “2014-10-12 15:37:00” 到 “2014-10-12 15:43:53” 之间的时间所对应的 Task 任务被取消了,不执行了。这就是 Task 任务不追赶的情况。

6.验证 scheduleAtFixedRate 方法具有追赶执行性

Run6.java

Java多线程学习之定时器 Timer_第40张图片

运行结果

Java多线程学习之定时器 Timer_第41张图片

scheduleAtFixedRate方法可以快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。两个时间段内所对应的 Task 任务被 “补充性” 执行了,这就是 Task 任务追赶执行的特性。

你可能感兴趣的:(Java多线程学习之定时器 Timer)