摘要:笔记来源定时任务调度基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。可安排任务执行一次,或者定期重复执行。有且仅有一个后台线程对多个业务线程进行定时定频率的调度。
笔记来源:IMOOC Java Timer定时任务调度
基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。
Timer 定义一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
有且仅有一个后台线程对多个业务线程进行定时定频率的调度。
Timer 主要构建 Timer 主要成分 Timer 定时调度函数 schedule 的四种用法
schedule(task, time)
参数
task - 所要安排的任务
time - 执行任务的时间
作用
在时间等于或超过time的时候执行且仅执行一次task
schedule(task, time, period)
参数
task - 所要安排的任务
time - 首次执行任务的时间
period - 执行一次task的时间间隔,单位是毫秒
作用
时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
schedule(task, delay)
参数
task - 所要安排的任务
delay - 执行任务前的延迟时间,单位是毫秒
作用
等待delay毫秒后执行且仅执行一次task
schedule(task, delay, period)
参数
task - 所要安排的任务
delay - 执行任务前的延迟时间,单位是毫秒
period - 执行一次task的时间间隔,单位是毫秒
作用
等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
scheduleAtFixedRate 的两种用法
scheduleAtFixedRate(task, time, period)
参数
task - 所要安排的任务
time - 首次执行任务的时间
period - 执行一次task的时间间隔,单位是毫秒
作用
时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
scheduleAtFixedRate(task, delay, period)
参数
task - 所要安排的任务
delay - 执行任务前的延迟时间,单位是毫秒
period - 执行一次task的时间间隔,单位是毫秒
作用
等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
Timer 示例import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class MyTimerTask extends TimerTask { private String name; public MyTimerTask(String inputName) { name = inputName; } @Override public void run() { // 以 yyyy-MM-dd HH:mm:ss 的格式打印当前执行时间 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current exec time is: " + sf.format(calendar.getTime())); // 打印当前name的内容 System.out.println("Current exec name is: " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1. 创建一个timer实例 Timer timer = new Timer(); // 2. 创建一个MyTimerTask实例 MyTimerTask myTimerTask = new MyTimerTask("No.1"); /** * 获取当前时间,并设置成距离当前时间三秒后的时间 */ Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current main time is: " + sf.format(calendar.getTime())); calendar.add(Calendar.SECOND, 3); // 3. 通过timer定时定频率调用myTimerTask的业务逻辑 //-------------------schedule的四种用法-------------------// /** * 在时间等于或超过time的时间执行且仅执行一次task */ myTimerTask.setName("schedule_1"); timer.schedule(myTimerTask, calendar.getTime()); /** * 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task */ myTimerTask.setName("schedule_2"); timer.schedule(myTimerTask, calendar.getTime(), 2000); /** * 等待delay毫秒后执行且仅执行一次task */ myTimerTask.setName("schedule_3"); timer.schedule(myTimerTask, 1000); /** * 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task */ myTimerTask.setName("schedule_4"); timer.schedule(myTimerTask, 3000, 2000); //--------------scheduleAtFixedRate的两种用法-------------// /** * 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task */ myTimerTask.setName("scheduleAtFixedRate_1"); timer.scheduleAtFixedRate(myTimerTask, calendar.getTime(), 2000); /** * 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task */ myTimerTask.setName("scheduleAtFixedRate_2"); timer.scheduleAtFixedRate(myTimerTask, 3000, 2000); } }schedule 与 scheduleAtFixedRate 的区别 首次计划执行的时间早于当前的时间
schedule 方法
fixed-delay;如果第一次执行时间被 delay 了,随后的执行时间按照上一次实际执行完成的时间点进行计算
scheduleAtFixedRate 方法
fixed-rate;如果第一次执行时间被 delay 了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此 TimerTask 中的执行体需要考虑同步
任务执行所需时间超出任务的执行周期间隔
schedule 方法
下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
scheduleAtFixedRate 方法
下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性
其他重要函数TimerTask 的 cancel()、scheduleExecutionTime()
Timer 的 cancel()、purge()
TimerTask 的两个重要函数
cancel()
作用:取消当前 TimerTask 里的任务
scheduleExecutionTime()
作用:返回此任务最近实际执行的已安排执行的实际
返回:最近发生此任务执行安排的时间,为Long类型
Timer 的其他函数
cancel()
终止此计时器,丢弃所有当前已安排的任务
purge()
作用:从此计时器的任务队列中移除所有已取消的任务
返回:从队列中移除的任务数
Timer 函数的综合应用
模拟两个机器人的定时行为
第一个机器人会隔两秒打印最近一次计划的时间、执行内容
第二个机器人会模拟往桶里倒水,直到桶里的水满为止,然后停止工作
桶里的水满了之后,第一个机器人再跳舞两秒钟,然后停止工作
/** * 跳舞的机器人 */ public class DancingRobot extends TimerTask { @Override public void run() { // 获取最近的一次任务执行的时间,并将其格式化 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Scheduled exec time is: " + sf.format(scheduledExecutionTime())); System.out.println("Dancing happily!"); } } /** * 倒水的机器人 */ public class WaterRobot extends TimerTask { private Timer timer; // 最大容量为5L private Integer bucketCapacity = 0; public WaterRobot(Timer inputTimer) { timer = inputTimer; } @Override public void run() { // 灌水直接至桶满为止 if(bucketCapacity < 5){ System.out.println("Add 1L water into the bucket!"); bucketCapacity ++; } else { // 水满之后就停止执行 System.out.println("The number of canceled task in timer is: " + timer.purge()); cancel(); System.out.println("The waterRobot has been aborted"); System.out.println("The number of canceled task in timer is: " + timer.purge()); System.out.println("Current water is " + bucketCapacity + "L"); // 等待两秒钟,终止timer里面的所有内容 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); } } } public class Executor { public static void main(String[] args) { Timer timer = new Timer(); // 获取当前时间 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current time is: " + sf.format(calendar.getTime())); DancingRobot dr = new DancingRobot(); WaterRobot wr = new WaterRobot(timer); timer.schedule(dr, calendar.getTime(), 2000); timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000); } }Timer 的缺陷
管理并发任务的缺陷
Timer 有且只有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符
当任务抛出异常时的缺陷
如果 TimerTask 抛出 RuntimeException,Timer 会停止所有任务的运行
Timer 的使用禁区对时效性要求较高的多任务并发作业
对复杂的任务的调度
扩展阅读Timer与ScheduledExecutorService间的抉择
Java中定时任务的实现:Timer与ScheduledExecutorService的不同
Java 几种调度任务的Timer、ScheduledExecutor、 开源工具包 Quartz、开源工具包 JCronTab
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71653.html
时间:2017年05月24日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:无个人学习源码:https://github.com/zccodere/s... 第一章:课程介绍 1-1 课程介绍 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务 在Java中的定时调度工具 Timer:小弟,能实现日常60%的定...
摘要:类是一个抽象类,由安排为一次执行或重复执行的任务。也是自带的一个基于线程池设计的定时任务类。问题,则可以直接使用类实现自定义的定时调度规则。 定时调度作为后端开发人员,我们总会遇到这样的业务场景:每周同步一批数据;每半个小时检查一遍服务器运行状况;每天早上八点给用户发送一份包含今日待办事项的邮件,等等。 这些场景中都离不开定时器,就像一个定好时间规则的闹钟,它会在指定时间触发,执行我们...
阅读 3191·2023-04-26 01:39
阅读 3344·2023-04-25 18:09
阅读 1611·2021-10-08 10:05
阅读 3227·2021-09-22 15:45
阅读 2757·2019-08-30 15:55
阅读 2392·2019-08-30 15:54
阅读 3166·2019-08-30 15:53
阅读 1323·2019-08-29 12:32