Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。定义了主要有以下6个方法:
顾名思义,schedule与scheduleAtFixedRate 的区别就是——是否按固定速率执行安排指定的任务。
一般情况下,timer的schedule和scheduleAtFixedRate方法没有区别,只在某个情况出现时会有区别--当前任务没有来得及完成下次任务又交到手上。
蓝色星辰 https://www.cnblogs.com/snailmanlilin/p/6873802.html 在这里举个例子:
暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业。
老师要求学生暑假每天写2页,30天后完成作业。
这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业。任务被拖延了。
这时候两个学生采取的策略就不同了:
schedule重新安排了任务时间,旅游回来的第一天做第11天的任务,第二天做第12天的任务,最后完成任务花了35天。
scheduleAtFixedRate是个守时的学生,她总想按时完成老师的任务,于是在旅游回来的第一天把之前5天欠下的任务以及第16天当天的任务全部完成了,之后还是按照老师的原安排完成作业,最后完成任务花了30天。
Ling912 对schedule和scheduleAtFixedRate的区别做了具体阐述:https://blog.csdn.net/ling912439122/article/details/52712406
在这里我主要学习了其中的Timer.scheduleAtFixedRate()方法。
import java.util.Timer;
import java.util.TimerTask;
TimerTask task = new TimerTask() {
@Override
public void run() {
//自定义
}
};
public void scheduleAtFixedRate(TimerTask task,long delay,long period)
public void scheduleAtFixedRate(TimerTask task,Date firstTime,long period)
参数
-
task--这是被调度的任务。其中TimerTask是一个实现了run方法的一个类,而具体的TimerTask需要自定义
-
firstTime--这是首次在该任务将被执行。
-
delay--这是以毫秒为单位的延迟之前的任务执行。
-
period-- 这是在连续执行任务之间的毫秒的时间。
具体代码实现内容为:
public void schedule(TimerTask task, long delay, long period)
这个方法是调度一个task,在delay(ms)后开始调度,每次调度完后,最少等待period(ms)后才开始调度。
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
调度一个task,在delay(ms)后开始调度,然后每经过period(ms)再次调度。这一句描述是和schedule是一样的,但是具体内容不然。
schedule在计算下一次执行的时间的时候,是通过当前时间(在任务执行前得到) + 时间片,而scheduleAtFixedRate方法是通过当前需要执行的时间(也就是计算出现在应该执行的时间)+ 时间片。前者是运行的实际时间,而后者是理论时间点,
例如:schedule时间片是5s,那么理论上会在5、10、15、20这些时间片被调度,但是如果由于某些CPU征用导致未被调度,假如等到第8s才被第一次调度,那么schedule方法计算出来的下一次时间应该是第13s而不是第10s,这样有可能下次就越到20s后而被少调度一次或多次。
scheduleAtFixedRate方法就是每次理论计算出下一次需要调度的时间用以排序,若第8s被调度,那么计算出应该是第10s,所以它距离当前时间是2s,那么再调度队列排序中,会被优先调度,那么就尽量减少漏掉调度的情况。
和上一个schedule方法类似,唯一的区别就是传入的第二个参数为第一次调度的时间。
public void schedule(TimerTask task, Date firstTime, long period)
public void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
和上一个scheduleAtFixedRate方法类似,唯一的区别就是第一次调度时间设置为一个Date时间,而不是当前时间的一个时间片。
参考文献:
一个很厉害的作者!!
https://www.cnblogs.com/0201zcr/p/4703061.html