schedule重新安排了任务时间,旅游回来的第一天做第11天的任务,第二天做第12天的任务,最后完成任务花了35天 。
scheduleAtFixedRate是个守时的学生,她总想按时完成老师的任务,于是在旅游回来的第一天把之前5天欠下的任务以及第16天当天的任务全部完成了,之后还是按照老师的原安排完成作业,最后完成任务花了30天 。
例2:
固定速率就好比你今天加班到很晚,但是到了第二天还必须准点到公司上班,如果你一不小心加班到了第二天早上 9 点,你就连休息的时间都没有了 。
而固定时延的意思是你必须睡够 8 个小时再过来上班,如果你加班到凌晨 6 点,那就可以下午过来上班了 。
固定速率强调准点,固定时延强调间隔 。
如果任务必须每天准点调度,那就应该使用固定速率调度,并且要确保每个任务执行时间不要太长,避免超过period间隔 。
如果任务需要每隔几分钟跑一次,那就使用固定时延调度,它不是很在乎单个任务要跑多长时间 。
我们来模拟一下这个情况 。
首先,我们对TimerTask进行修改,让它某一次任务产生大量耗时:
TimerTask task = new TimerTask() {private int i = 1;@Overridepublic void run() {System.out.print(i + " " + DateUtil.formatNow() + " 开始执行, ");if(i == 3) {ThreadUtil.sleep(11 * 1000);}System.out.println(DateUtil.formatNow() + " 结束");i++;}};
该任务在执行第3次时,将会休眠11秒,这将会导致延误后续的任务 。
2. 固定速率示例:
Timer timer = new Timer("timer");timer.scheduleAtFixedRate(task, 5000, 2000);
设定任务延迟5秒后执行第1次任务,之后每2秒执行一次 。
输出:
启动于:2022-10-31 15:51:241 2022-10-31 15:51:29 开始执行, 2022-10-31 15:51:29 结束2 2022-10-31 15:51:31 开始执行, 2022-10-31 15:51:31 结束3 2022-10-31 15:51:33 开始执行, 2022-10-31 15:51:44 结束 *4 2022-10-31 15:51:44 开始执行, 2022-10-31 15:51:44 结束 *5 2022-10-31 15:51:44 开始执行, 2022-10-31 15:51:44 结束 *6 2022-10-31 15:51:44 开始执行, 2022-10-31 15:51:44 结束 *7 2022-10-31 15:51:44 开始执行, 2022-10-31 15:51:44 结束 *8 2022-10-31 15:51:44 开始执行, 2022-10-31 15:51:44 结束 *9 2022-10-31 15:51:45 开始执行, 2022-10-31 15:51:45 结束10 2022-10-31 15:51:47 开始执行, 2022-10-31 15:51:47 结束11 2022-10-31 15:51:49 开始执行, 2022-10-31 15:51:49 结束
如果不存在第3次耗时11秒的情况下,正常任务执行时间应该为:
启动于:2022-10-31 15:51:241 2022-10-31 15:51:29 开始执行, 2022-10-31 15:51:29 结束2 2022-10-31 15:51:31 开始执行, 2022-10-31 15:51:31 结束3 2022-10-31 15:51:33 开始执行, 2022-10-31 15:51:33 结束 *4 2022-10-31 15:51:35 开始执行, 2022-10-31 15:51:35 结束 *5 2022-10-31 15:51:37 开始执行, 2022-10-31 15:51:37 结束 *6 2022-10-31 15:51:39 开始执行, 2022-10-31 15:51:39 结束 *7 2022-10-31 15:51:41 开始执行, 2022-10-31 15:51:41 结束 *8 2022-10-31 15:51:43 开始执行, 2022-10-31 15:51:43 结束 *9 2022-10-31 15:51:45 开始执行, 2022-10-31 15:51:45 结束10 2022-10-31 15:51:47 开始执行, 2022-10-31 15:51:47 结束11 2022-10-31 15:51:49 开始执行, 2022-10-31 15:51:49 结束
但是在第3次执行任务时因为执行耗时11秒,第4次本该在15:51:35开始执行并完成任务,却到了15:51:44才执行完成,这11秒延误了后续5个任务的正常执行,因此在15:51:44时,scheduleAtFixedRate赶作业把延误的5个任务一起执行了 。
最后赶上了原本的进度,第9个任务准时在15:51:45执行 。
3. 固定延时示例:
Timer timer = new Timer("timer");timer.schedule(task, 5000, 2000);
输出:
启动于:2022-10-31 15:56:591 2022-10-31 15:57:04 开始执行, 2022-10-31 15:57:04 结束2 2022-10-31 15:57:06 开始执行, 2022-10-31 15:57:06 结束3 2022-10-31 15:57:08 开始执行, 2022-10-31 15:57:19 结束 *4 2022-10-31 15:57:19 开始执行, 2022-10-31 15:57:19 结束5 2022-10-31 15:57:21 开始执行, 2022-10-31 15:57:21 结束6 2022-10-31 15:57:24 开始执行, 2022-10-31 15:57:24 结束7 2022-10-31 15:57:26 开始执行, 2022-10-31 15:57:26 结束8 2022-10-31 15:57:28 开始执行, 2022-10-31 15:57:28 结束9 2022-10-31 15:57:30 开始执行, 2022-10-31 15:57:30 结束10 2022-10-31 15:57:32 开始执行, 2022-10-31 15:57:32 结束
经验总结扩展阅读
- 三 Java多线程-ThreadPool线程池
- 液晶电视机选购技巧 教你选购使用与维护电视机
- 二 Java多线程-线程关键字
- 二 Java 编码那些事
- 一 Java多线程-线程生命周期
- SpringBoot 常用注解的原理和使用
- 椰浆稀释用热水还是冻水
- 毛巾发黄怎么洗又干净又软
- 衣物洗过缩水怎么办
- 搪瓷锅第一次使用怎么开锅