美文网首页
Java多线程学习之定时器 Timer

Java多线程学习之定时器 Timer

作者: Steven1997 | 来源:发表于2018-04-22 10:36 被阅读19次

    定时 / 计划功能

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

    定时器 Timer 的使用


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

    常用方法

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



    方法如下:


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

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

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

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

    Run1.java


    运行结果

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

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

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

    运行结果


    可以看到主线程运行完毕,守护线程中的任务未执行线程就结束了。
    2.计划时间早于当前时间:提前运行的效果

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

    示例代码


    运行结果
    3.多个 TimerTask 任务及延时的测试

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



    运行结果

    Timer 是以队列的形式排队执行的,所以执行的时间可能和预期的时间不一致,因为前面的任务可能消耗时间较长,则后面的任务运行的时间也会被延迟。
    Run2Later.java

    运行结果

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

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

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

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

    Run.java

    运行结果


    从运行结果来看,每隔 4 秒运行一次 TimerTask 任务,并且是无限期地重复执行。
    2.计划时间早于当前时间:提前运行的效果

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

    运行结果

    3.任务执行时间被延迟

    Run2_1.java


    运行结果

    任务被延迟但还是一个一个顺序运行。
    4.TimerTask 类的 cancel() 方法

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


    运行结果

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

    5.Timer 类的 cancel() 方法

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


    运行结果

    TimerTaskA运行一次后所有任务都被移除。
    6.Timer 的 cancel() 方法注意事项

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


    运行结果

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

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

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

    运行结果


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

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

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

    Run.java


    运行结果

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

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

    1.测试 schedule 方法不延时

    Run1.java


    运行结果


    如果执行任务的时间没有被延迟,则下一次执行时间是上一次任务的开始时间加上 delay 时间。
    2.测试 schedule 方法延时

    Run2.java

    运行结果


    如果执行任务的时间被延迟,那么下一次任务的执行时间以上一次任务“结束”的时间为参考来计算。
    3.测试 scheduleAtFixedRate 方法不延时

    Run3.java


    运行结果

    如果执行任务的时间没有被延迟,则下一次执行时间是上一次任务的开始时间加上 delay 时间。
    4.测试 scheduleAtFixedRate 方法延时

    Run4.java



    运行结果

    如果执行任务的时间被延迟,那么下一次任务的执行时间以上一次任务“结束”的时间为参考来计算。
    5.验证 schedule 方法不具有追赶执行性

    Run5.java



    运行结果

    时间 “2014-10-12 15:37:00” 到 “2014-10-12 15:43:53” 之间的时间所对应的 Task 任务被取消了,不执行了。这就是 Task 任务不追赶的情况。
    6.验证 scheduleAtFixedRate 方法具有追赶执行性

    Run6.java


    运行结果


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

    相关文章

      网友评论

          本文标题:Java多线程学习之定时器 Timer

          本文链接:https://www.haomeiwen.com/subject/nwdflftx.html