由于提出的问题是,如果计时器任务花费的时间比间隔时间长,那么计时器的行为方式。
我编写了一个愚蠢的示例程序来观察计时器的行为:
public class FlawedTimerTask extends TimerTask {
final int taskId;
final long sleepTime;
int counter = 0;
public FlawedTimerTask(int taskId, long sleepTime) {
super();
this.taskId = taskId;
this.sleepTime = sleepTime;
}
@Override
public void run() {
long beginTimeInNs = System.nanoTime();
System.out.println("taskId=" + taskId + ", run=" + counter + ", beginning at " + (beginTimeInNs-beginOfExperiment));
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTimeInNs = System.nanoTime();
System.out.println("taskId=" + taskId + ", run=" + counter + ", ending at " + (endTimeInNs-beginOfExperiment));
counter++;
}
static long beginOfExperiment;
public static void main(String[] args) {
beginOfExperiment = System.nanoTime();
Timer timer = new Timer();
timer.schedule(new FlawedTimerTask(1, 800), 500, 500);
timer.schedule(new FlawedTimerTask(2, 1000), 500, 2500);
}
}
输出是:
taskId=1, run=0, beginning at 491988762
taskId=1, run=0, ending at 1291944877
taskId=2, run=0, beginning at 1292056514
taskId=2, run=0, ending at 2293928680
taskId=1, run=1, beginning at 2294036467
taskId=1, run=1, ending at 3094967160
taskId=1, run=2, beginning at 3095097404
taskId=1, run=2, ending at 3894902745
taskId=1, run=3, beginning at 3895045820
taskId=1, run=3, ending at 4695902088
taskId=2, run=1, beginning at 4696095849
taskId=2, run=1, ending at 5695887973
taskId=1, run=4, beginning at 5695991911
taskId=1, run=4, ending at 6496896941
taskId=1, run=5, beginning at 6497002803
taskId=1, run=5, ending at 7297814161
taskId=1, run=6, beginning at 7297998297
taskId=1, run=6, ending at 8098803239
taskId=2, run=2, beginning at 8098922575
taskId=2, run=2, ending at 9098814787
taskId=1, run=7, beginning at 9098971977
taskId=1, run=7, ending at 9899803866
taskId=1, run=8, beginning at 9899970038
taskId=1, run=8, ending at 10699807458
taskId=1, run=9, beginning at 10699912038
taskId=1, run=9, ending at 11500693882
taskId=2, run=3, beginning at 11500815143
taskId=2, run=3, ending at 12501656270
taskId=1, run=10, beginning at 12501781380
taskId=1, run=10, ending at 13302714640
taskId=1, run=11, beginning at 13302888511
taskId=1, run=11, ending at 14102727215
taskId=1, run=12, beginning at 14102929958
taskId=1, run=12, ending at 14903695762
taskId=2, run=4, beginning at 14903878616
taskId=2, run=4, ending at 15903607223
taskId=1, run=13, beginning at 15903775961
taskId=1, run=13, ending at 16705705613
taskId=1, run=14, beginning at 16705798644
taskId=1, run=14, ending at 17505650180
taskId=1, run=15, beginning at 17505881795
taskId=1, run=15, ending at 18306578307
taskId=2, run=5, beginning at 18306718815
taskId=2, run=5, ending at 19306666847
taskId=1, run=16, beginning at 19306757953
taskId=1, run=16, ending at 20107480129
taskId=1, run=17, beginning at 20107580217
taskId=1, run=17, ending at 20907534407
taskId=1, run=18, beginning at 20907640911
taskId=1, run=18, ending at 21709616117
taskId=2, run=6, beginning at 21709784855
taskId=2, run=6, ending at 22709563506
taskId=1, run=19, beginning at 22709664236
taskId=1, run=19, ending at 23510559642
taskId=1, run=20, beginning at 23510653956
taskId=1, run=20, ending at 24310465713
taskId=1, run=21, beginning at 24310572217
taskId=1, run=21, ending at 25111451583
taskId=2, run=7, beginning at 25111549105
taskId=2, run=7, ending at 26111453508
taskId=1, run=22, beginning at 26111544614
taskId=1, run=22, ending at 26913489022
taskId=1, run=23, beginning at 26913629531
taskId=1, run=23, ending at 27713421398
taskId=1, run=24, beginning at 27713577305
taskId=1, run=24, ending at 28514443839
taskId=2, run=8, beginning at 28514550985
taskId=2, run=8, ending at 29514349525
taskId=1, run=25, beginning at 29514496450
taskId=1, run=25, ending at 30315367475
taskId=1, run=26, beginning at 30315469488
taskId=1, run=26, ending at 31115349896
taskId=1, run=27, beginning at 31115475648
taskId=1, run=27, ending at 31917465609
taskId=2, run=9, beginning at 31917563773
taskId=2, run=9, ending at 32917368087
taskId=1, run=28, beginning at 32917524636
taskId=1, run=28, ending at 33718337276
taskId=1, run=29, beginning at 33718481634
taskId=1, run=29, ending at 34518366533
taskId=1, run=30, beginning at 34518459564
taskId=1, run=30, ending at 35319336363
taskId=2, run=10, beginning at 35319516009
taskId=2, run=10, ending at 36319338930
taskId=1, run=31, beginning at 36319440301
taskId=1, run=31, ending at 37121299378
taskId=1, run=32, beginning at 37121403957
taskId=1, run=32, ending at 37921223413
taskId=1, run=33, beginning at 37921324785
taskId=1, run=33, ending at 38722168863
taskId=2, run=11, beginning at 38722270877
taskId=2, run=11, ending at 39722259328
你可以观察到
- 计时器在计时器任务的间隔(800ms,1000ms)中运行,而不是在其间隔 500ms
- 定时器任务之间没有交错发生(在单线程定时器的实现中,主循环中有一个阻塞调用)