Timer在处理任务调度时常会碰到各种问题,通过两个特例了解Timer两种调度方式的区别:
1、任务调度实际开始执行时间慢于计划调度时间,如某个任务计划开始时间为2018-06-24
00:19:00,每隔2s调度一次,但实际开始时间为2018-06-24
00:19:06,比计划晚了6秒钟。
2、任务调度时间间隔为2秒钟(每隔两秒钟执行一次任务),但实际调度中每次任务执行的时间为3秒钟,大于间隔时间。
以下是schedule、scheduleAtFixedRate
两种调度方式对这两种情况的处理:
调度方式
第一种情况
第二种情况
schedule
以实际开始时间为基准进行任务调度,第一次调度时间为2018-06-24
00:19:06,以后每隔2s调度一次。
任务调度完成后再执行下一次调度,即调整调度间隔时间为3s。
scheduleAtFixedRate
以计划开始时间为基准进行任务调度,在短期内缩短间隔时间进行高频率任务调度弥补次数。任务开始比计划开始晚了6秒钟,调度时间间隔缩短直到弥补相应次数再恢复为预设间隔时间2s。
以并发方式进行任务调度,每隔2s种执行一次任务,即使上次任务还没调度完成。
针对第一种情况的测试:
测试用例:
计划调度时间:当前时间的前6秒
调度间隔:2s
schedule测试结果:
current system time
is:2018-06-24 12:47:29
plan execution time
is:2018-06-24 12:47:23
current execute time
is:2018-06-24 12:47:29
current execute time
is:2018-06-24 12:47:31
current execute time
is:2018-06-24 12:47:33
current
execute time is:2018-06-24 12:47:35
scheduleAtFixedRate测试结果:
current system time
is:2018-06-24 12:49:16
plan execution time
is:2018-06-24 12:49:10
current execute time is:2018-06-24 12:49:10
current execute time is:2018-06-24 12:49:12
current execute time is:2018-06-24 12:49:14
current execute time is:2018-06-24 12:49:16
current execute time
is:2018-06-24 12:49:18
current
execute time is:2018-06-24 12:49:20
标红的几次任务调度几乎同时出现。
针对第二种情况的测试:
测试用例:
计划调度时间:当前时间的前6秒
调度间隔:2s
任务调度时调用Thread.sleep方法让线程睡眠3s
schedule测试结果:
plan execution time
is:2018-06-24 12:55:13
current execute time
is:2018-06-24 12:55:13
current execute time
is:2018-06-24 12:55:16
current
execute time is:2018-06-24 12:55:19
可以看到任务调度间隔调整为3s种一次。
scheduleAtFixedRate测试结果:
plan execution time
is:2018-06-24 12:57:52
current execute time
is:2018-06-24 12:57:52
current execute time
is:2018-06-24 12:57:54
current
execute time is:2018-06-24 12:57:56
每隔2s进行一次任务调度,多次调度并发运行。