Java定时任务调度工具–Timer和Quart
Timer是JDK直接提供的,Quart是需要导入jar包的。
Timer只有一个后台线程去执行任务,Quart有多个线程执行。
Timer工具位于java.util.Timer中,可以上官方文档查看API.
TimerThread是后台的一个主线程,TaskQueue是一个业务线程TimerTask的一个队列。TimerTask调用其run方法实现业务逻辑。
其原理就是TimerThread定期调用TaskQueue中的TimerTask来实现定时任务。我们使用这个包时,只需关注Timer和TimerTask,其他两个对我们是透明的。
放上demo
Timer主类
package time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
public class MyTimer extends Timer{
public static void main(String[] args){
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个TimerTasker实例
TimeTasker task2 = new TimeTasker("No.1");
//3.通过timer定时调用task1的业务逻辑
//即第一次执行是在当前时间的两秒之后,之后每隔一秒执行一次
//timer.schedule(task1, 2000L,1000L);
//设置当前时间的后5秒
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current time is :" + sf.format(calendar.getTime()));
calendar.add(Calendar.SECOND, 5);
//-----------schedule的用法-----------//
//1.按规定时间调度一次
//timer.schedule(task2, calendar.getTime());
//2.在规定时间执行,之后每隔固定时间再次执行
task2.setName("No.3");
timer.schedule(task2, calendar.getTime(),2000L);
//3.在距离当前时间delay秒之后,执行一次task
task2.setName("No.4");
timer.schedule(task2, 3000L);
//4.在距离当前时间delay秒之后,执行一次task,之后每隔几秒钟之后再次执行
task2.setName("No.5");
timer.schedule(task2, 3000L,1000L);
//接下来是scheduleAtFixedRate(,,,)和schedule有一点点不同,参数意义一样,函数
//实现的功能在一些特殊情况略有差异
task2.setName("scheduleAtFixedRate");
timer.scheduleAtFixedRate(task2, 2000L, 3000L);
//-------------cancle的用法------------//
//Timer下的cancel方法,终止这个计时器,丢弃所有当前安排的任务
//timer.cancel();
//timer.purge();移除队列中已经被取消的任务。
}
}
TimerTask定时业务逻辑类
package time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
public class TimeTasker2 extends TimerTask{
private String name;
public TimeTasker2(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前那么的内容
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);
//---TimerTask中的cancel能够取消他自己的定时任务
//scheduledExecutionTime()返回发生此任务执行安排的时间 Long型数据
}
}
介绍一下schedule 和 scheduleAtFixedRate两个函数的区别
1.首次计划执行的时间早于当前的时间
schedule:如果第一次执行的时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算
即你打算让他在当前时间的前6秒开始执行,所以你运行程序的时候,他的执行时间显示的不是6秒前,而是当前时间
scheduleAtFixedRate:如果第一次执行的时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,
并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步
2.任务执行所需要的时间超出任务的执行周期间隔
schedule:下一次执行时间相对与上一次实际执行完成的时间,因此执行时间会不断延后。
scheduleAtFixedRate:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性。
Timer的缺陷
1.管理并发任务的缺陷,两个task同时运行就会出错。不会同时执行,只能一个接一个。
2.当任务抛出异常时的缺陷,当抛出异常时,Timer会停止所有任务的执行