Timer,一般用来做延时任务或者循环定时执行的任务。
例如:指定在一小时后闹钟就响了,或者每天6:00响,这些都是延时任务或者是定时循环的任务
使用Timer的时候,必须要有一个TimerTask去执行任务,这是一个线程,它实现了Runnable接口,run方法里面就是线程需要做的,也是我们自己定义的。
下面来看代码:
上面几行代码只是定义了一个Date和一个Timer,以及一个TimerTask
下面来看看使用:
代码前两行,只接收两个参数,分别是TimerTask和时间,这两种使用方式都是只执行一次,不是循环执行的。
第一行:在指定时间的时候去执行传递进去的TimerTask,不循环执行
第二行:延时一段时间后执行TimerTask,这里指的是延时1秒钟后执行TimerTask
中间两行涉及到了循环执行,比前两行多传递了一个参数,也就是间隔时间。间隔一段时间执行一次TimerTask
第三行:一秒后执行TimerTask,并且每隔1秒执行一次(第二个参数是延时,第三个参数是间隔时间)
第四行:在指定的时间执行TimerTask,并且开始每隔1秒执行一次
接下来重点来了,后面两个方法。后面两个方法,看起来就和前面来两个方法就不一样了,哈哈。
究竟怎么样,往下看。
第五行:其实和第三行是一样的,都是延时执行,然后每次间隔一定的时间执行一次TimerTask
第六行:这行和第四行就有区别了,相同的是:都是在指定的时间开始执行,然后每隔一段时间执行。
不同的是:schedule在执行的时候,如果Date过了,也就是Date是小于现在时间,那么会立即执行一次,然后每隔一段时间执行,
scheduleAtFixedRate在执行的时候,如果Date过了。还会执行,然后才是每隔一段时间执行。
看代码执行的结果:
这个是schedule的执行结果,你会发现,如果这个时间过了,会直接执行,然后开始每隔一秒后执行。
下面来看看scheduleAtFixedRate的执行结果。
这是scheduleAtFixedRate的执行结果。这里是每隔5分钟执行一次,我这个是在大概17:08分执行的,我这里指定的时间是:16:30
从16:30开始算,每隔5分钟,也就是16:30 16:35 16:40 16:45 16:50 16:55 17:00 17:05分别执行一次,算下来刚好是8次,这就对了,所以我们刚运行的时候一次性执行了8次,然后打印结果中,最后一次是在17:10的时候执行的。你就会发现,其实最后一次和倒数第二次的间隔不是5分钟,而是刚好是17:10的当前毫秒数。
这就是两者间的差别了,schedule是直接执行,并且以此刻为开始时间,开始执行,并且过去的不再执行。而scheduleAtFixedRate是判断时间,如果过了,那么就算出之前执行的次数,依次执行,然后等待下一次执行时间的到来。下一次就是17:10,而不是17:13(17:08的后5分钟)。
这就是两者最大的差别。
最后来看看第五行和第三行有什么区别,其实没什么区别,来看源码:
看这两个方法的源码,几乎一样,就在于最后一个参数的传递。一个传递的是 -period 一个传递的是 period
接下来继续看。
我们先来看看代码中的第一个红框中的第一行代码。里面计算的是绝对值,和正负数没关系吧!然后第二个红框,直接赋值,就没有下文了。
接下来继续看看TimerTask里面的代码:
这里只涉及到了一个同步,最后return的时候,判断一下,如果延时时间是小于0的话就加,大于0就减,那没什么区别嘛,加一个负数和减一个正数有啥区别,所以得出结论,没区别。
看到这里我都怀疑我学了多年的数学是否过关了。想当年每次都是数一数二的数学成绩,看到这里已经懵逼了,到最后都是一样的,这里我就搞不懂了,为什么一个是传负,一个是传正呢?