什么是定时任务调度
基于给定的时间点,给定的时间间隔或者给定的执行次数,自动执行的任务。
定时调度工具
Timer
Quartz
Timer | Quartz | |
---|---|---|
出生不同 | JDK自带 | 开源 |
能力区别 | 什么时间执行什么程序 | 功能更强大 |
底层机制 | 只有一个后台线程执行任务 | 拥有后台执行线程池能够使用多个线程执行任务 |
能用 Timer 处理的时候,尽量用 Timer 处理。因为 Quartz 需要的资源更多(写法也不一样)。
Timer的定义
有且仅有一个后台线程对多个业务线程进行定时定频率的调度
主要构件:
Timer定时调用TimerTask
Timer工具类详解:
1、MyTimerTask.java
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
/*打印当前name的内容*/
Calendar cale = Calendar.getInstance();
System.out.println("Current exec name is : "+name+",Time:"+cale.getTime());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、MyTimer.java
public class MyTimer {
public static void main(String[] args){
//1、创建一个timer实例
Timer timer = new Timer();
// 2、创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
// 3、通过timer定时定频率调用myTimerTask的业务逻辑。
// 即第一次执行时在当前时间的2S之后,之后每隔1S执行一次。
timer.schedule(myTimerTask,2000L,1000L);
}
}
3、执行结果:
Current exec name is : No.1,Time:Mon Oct 29 11:06:55 CST 2018
Current exec name is : No.1,Time:Mon Oct 29 11:06:56 CST 2018
Current exec name is : No.1,Time:Mon Oct 29 11:06:57 CST 2018
Current exec name is : No.1,Time:Mon Oct 29 11:06:58 CST 2018
Current exec name is : No.1,Time:Mon Oct 29 11:06:59 CST 2018
Current exec name is : No.1,Time:Mon Oct 29 11:07:00 CST 2018
……
Timer定时函数的用法
schedule的四种用法
方法 | 参数 | 作用 | |
---|---|---|---|
1 | schedule(task,time) | task:所要安排的任务 time:执行任务的时间 | 在时间等于或超过time的时候执行且仅执行一次task |
2 | schedule(task,time,period) | task:所要安排的任务 time:执行任务的时间 period:执行一次task的时间间隔,单位是毫秒 | 在时间等于或超过time的时候,首次执行task 之后每隔period毫秒重复执行一次task |
3 | schedule(task,delay) | task:所要安排的任务 delay:执行任务前的延迟时间,单位是毫秒 | 等待delay毫秒后,执行且仅执行一次task |
4 | schedule(task,delay,period) | task:所要安排的任务 delay:执行任务前的延迟时间,单位是毫秒 period:执行一次task的时间间隔,单位是毫秒 | 等待delay毫秒后,首次执行task 之后每隔period毫秒重复执行一次task |
scheduleAtFixedRate的两种用法
MyTimer.java
public class MyTimer {
public static void main(String[] args){
//1、创建一个timer实例
Timer timer = new Timer();
// 2、创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
/*
// 3、通过timer定时定频率调用myTimerTask的业务逻辑。
// 即第一次执行时在当前时间的2S之后,之后每隔1S执行一次。
timer.schedule(myTimerTask,2000L,1000L);
*/
/*获取当前时间,并设置成距离当前时间3S之后的时间
* 如:当前时间2016-11-10 23:59:57
* 则设置后的时间则为2016-11-11 00:00:00
*
* */
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()));
calendar.add(Calendar.SECOND,3);
// --------schedule的用法 ------------------
/*1、在时间等于或超过time的时候执行且仅执行一次
* 如在2016-11-11 00:00:00执行一次task:打印任务的名称。
* */
// myTimerTask.setName("schedule1");
// timer.schedule(myTimerTask,calendar.getTime());
/*2、在时间等于或超过time的时候执行task
* 之后每隔period毫秒重复执行一次task
* 如在2016-11-11 00:00:00执行一次task:打印任务的名称。
* 之后每隔2S执行一次task
* */
// myTimerTask.setName("schedule2");
// timer.schedule(myTimerTask,calendar.getTime(),2000L);
/*3、等待delay毫秒后,执行且仅执行一次task
* 如在2016-11-11 00:00:00
* 则在2016-11-11 00:00:01执行一次task:打印任务的名字
*
* */
// myTimerTask.setName("schedule3");
// timer.schedule(myTimerTask,1000L);
/*4、等待delay毫秒后,首次task
* 之后每隔period毫秒重复执行一次task
* 如在2016-11-11 00:00:00
* 则在2016-11-11 00:00:01执行一次task:打印任务的名字
* 之后每隔2S执行一次task
* */
// myTimerTask.setName("schedule4");
// timer.schedule(myTimerTask,1000L,2000L);
//---------------- scheduleAtFixedRate的用法 -------------
/*1、在时间等于或超过time的时候执行task
* 之后每隔period毫秒重复执行一次task
* 如在2016-11-11 00:00:00执行一次task:打印任务的名称。
* 之后每隔2S执行一次task
* */
// myTimerTask.setName("scheduleAtFixedRate1");
// timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000L);
/*2、等待delay毫秒后,首次task
* 之后每隔period毫秒重复执行一次task
* 如在2016-11-11 00:00:00
* 则在2016-11-11 00:00:03执行一次task:打印任务的名字
* 之后每隔2S执行一次task
* */
myTimerTask.setName("scheduleAtFixedRate2");
timer.scheduleAtFixedRate(myTimerTask,3000L,2000L);
}
}
其他重要函数
TimerTask的cancel(),scheduledExecutionTime()
Timer的cancel(),purge()
类class | 方法 | 作用 | 返回值 |
---|---|---|---|
TimerTask | cancel() | 取消当前TimerTask里的任务 | |
TimerTask | scheduledExecutionTime() | 返回此任务最近实际执行的已安排执行的时间 | 最近发生此任务执行安排的时间,为long型 |
Timer | cancel() | 终止此计时器,丢弃所有当前已安排的任务 | |
Timer | purge() | 从此计时器的任务队列中移除所有已取消的任务 | 从队列中移除的任务数 |
schedule和scheduleAtFixedRate区别
首次计划执行的时间早于当前的时间 | 任务执行所需时间超出任务的执行周期间隔 | |
---|---|---|
schedule | “fixed-delay”;如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算 | 下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后 |
scheduleAtFixedRate | “fixed-rate”;如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的而知新题需要考虑同步 | 下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性 |
Timer函数的综合应用
实现两个机器人:
1、第一个机器人会隔2S打印最近一次计划的时间、执行内容
2、第二个机器人会模拟往桶里倒水,直到桶里的水满为止。
Timer缺陷
管理并发任务的缺陷 | Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符 |
当任务抛出异常时的缺陷 | 如果TimerTask抛出RuntimeException,Timer会停止索引任务的运行 |
Timer的使用禁区
对时效性要求较高的多任务并发作业
对复杂的任务的调度