学习视频地址:点击打开链接
1.什么是定时任务调度?
基于给定的时间点、给定的时间间隔或者给定的执行次数自动执行的任务
2.JDK提供的Timer是很常用的定时任务调度器
3.简单示例:
MyTimerTask代码:
package com.tg.demo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask{
private String name;
private Integer count=0;
public MyTimerTask(String name){
this.name=name;
}
//业务逻辑
@Override
public void run() {
if(count<3){
//以 yyyy-MM-dd HH:mm:ss格式打印执行时间
Calendar clCalendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("执行时间: "+sf.format(clCalendar.getTime()));
System.out.println("name: "+name);
count++;
}else{
cancel();
System.out.println("任务结束");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.tg.demo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
public class MyTimer {
public static void main(String[] args) {
Calendar clCalendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("当前时间: "+sf.format(clCalendar.getTime()));
//创建一个timer实例
Timer timer = new Timer();
//创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("aaaa");
//通过timer定时频率调用myTimerTask的业务逻辑
// //schedule(task,time,period) 时间等于或超过time时首次执行task 之后每隔period毫秒重复执行一次task
// timer.schedule(myTimerTask, 2000, 1000);//两秒后开始执行,然后每隔一秒执行一次
Calendar calendar =Calendar.getInstance();
calendar.add(Calendar.SECOND,3); //时间间隔3S
//schedule(task,time) 在时间等于或者超过time的时候仅执行一次task
timer.schedule(myTimerTask, calendar.getTime()); //3秒后执行一次
//scheduledExecutionTime()返回此任务最近实际执行的已安排执行的时间,返回值类型为long
System.out.println(sf.format(myTimerTask.scheduledExecutionTime()));
// //schedule(task,delay) 等待delay毫秒后执行且仅执行一次task
// timer.schedule(myTimerTask, 3000);
// //schedule(task,delay,period) 等待delay毫秒后首次执行task 之后每隔period毫秒重复执行一次task
// timer.schedule(myTimerTask, 3000L, 2000L);
// //scheduleAtFixedRate(task,time,period) 时间等于或超过time时首次执行task 之后每隔period毫秒重复执行一次task
// timer.scheduleAtFixedRate(myTimerTask, 3000, 2000);
// //scheduleAtFixedRate(task,delay,period) 等待delay毫秒后首次执行task 之后每隔period毫秒重复执行一次task
// timer.scheduleAtFixedRate(myTimerTask, 3000, 2000);
}
}
schedule的四种用法
schedule(task,time) 在时间等于或者超过time的时候仅执行一次task
schedule(task,time,period) 时间等于或超过time时首次执行task 之后每隔period毫秒重复执行一次task
schedule(task,delay) 等待delay毫秒后执行且仅执行一次task
schedule(task,delay,period) 等待delay毫秒后首次执行task 之后每隔period毫秒重复执行一次task
scheduleAtFixedRate的两种用法
scheduleAtFixedRate(task,time,period) 时间等于或超过time时首次执行task 之后每隔period毫秒重复执行一次task
scheduleAtFixedRate(task,delay,period) 等待delay毫秒后首次执行task 之后每隔period毫秒重复执行一次task
schedule与scheduleAtFixedRate的区别:
1、首次计划执行的时间早于当前的时间
schedule 如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算
scheduleAtFixedRate 如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,
并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需考虑同步
2、任务执行所需时间超出任务的执行周期间隔
schedule方法 下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
scheduleAtFixedRate方法 下一次执行的时间相对于上一次开始的时间,执行时间一般不会延后,因此存在并发性
其他函数
cancel() 取消当前TimerTask里的任务
scheduledExecutionTime() (返回最近一次的计划执行时间)返回此任务最近实际执行的已安排执行的时间,返回值类型为long
purge() 从此计时器的任务队列中移出所有已取消的任务 返回队列中移除的任务数
Timer缺陷:
1.管理并发任务的缺陷
Timer 有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符
2.当任务抛出异常时的缺陷
如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行
Timer的使用禁区
1.对时效性要求较高的多任务并发作业
2.对复杂的任务的调度
--------------------------------------------------------------------------------------
附:Timer和Quartz的区别
1.出身不同
Timer由JDK提供,调用方式简单粗暴,不需要别的jar包支持
Quartz源于开源项目,非JDK自带,需要引入别的jar包支持
2.能力区别:主要体现在对时间的控制上
Timer实现如某个具体时间执行什么任务
Quartz实现如每个星期天8点执行什么任务 Quartz的时间控制功能远比Timer强大和完善
3.底层机制
Timer走后台线程执行定时任务
Quartz能够使用多个执行线程去执行定时任务
尽管 Quartz比Timer强大很多,但是Timer能实现的功能,尽量不要动用Quartz