TimerTask的cancel()函数的作用:取消当前TimerTask里的任务
TimerTask的scheduleExecutionTime()作用:返回此任务最近实际执行的已安排执行的时间,返回值:最近发生此任务执行安排的时间,为long型
Timer的cancel()函数的作用:终止此计时器,丢弃所有当前已安排的任务
Timer的purge()函数的作用:从此计时器的任务队列中移除所有已取消的任务。返回值:从队列中移除的任务数。
TimerTask的cancel()、scheduledExecutionTime()
cancel():取消当前TimerTask里的任务。


scheduledExecutionTime():返回最近一次执行该定时任务的时间。

Timer的cancel()、purge()
cancel():Timer下的cancel()表示结束当前Timer的所有定时任务。

purge():表示从此Timer的定时任务队列中移除所有已经取消的定时任务,并且返回移除的个数。

首先我们先明确一下什么是定时任务调度?
基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。
Java中定时任务调动工具有俩:Timer 、Quartz
区别:
出身不同:Timer由jdk直接提供,不需jar包支持;Quartz需引入jar包。
能力不同:Timer简单定时任务;Quartz时间控制功能更强大。
底层机制:Timer只有一个后台线程执行;Quartz是多线程执行任务。
让我们看下官方文档api(JDK1.8)

可能有的小伙伴英语水平不太好,那让我们看下中文版吧:

那么我们可以归纳Timer的定义:有且仅有一个后台线程对多个业务线程进行定时定频率的调度
主要构件:

Timer工具类详解:

package com.leo.timer;import java.util.TimerTask;public class MyTimerTask extends TimerTask { private String name; public MyTimerTask(String inputName){
name=inputName;
} @Override
public void run() { //打印当前name的内容
System.out.println("Current exec name is"+name);
} public String getName() { return name;
} public void setName(String name) { this.name = name;
}
}package com.leo.timer;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"); //3.通过timer定时频率调用myTImerTask的业务逻辑
// 既第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
timer.schedule(myTimerTask,2000L,1000L);
}
}控制台打印显示:

作用:在时间等于或超过time的时候执行且仅执行一次task
参数: task-所要安排的任务
time-首次执行任务的时间
period-执行一次task的时间间隔,单位是毫秒
参数: task-所要安排的任务
delay-执行任务前的延迟时间,单位是毫秒
作用: 等待delay毫秒后执行且仅执行一次task
参数: task-所要安排的任务
delay-执行任务前的延迟时间,单位是毫秒
period-执行一次task的时间间隔,单位是毫秒
作用: 等待delay毫秒后执行且仅执行一次task,之后每隔period毫秒重复执行一次task
具体代码如下:
定时任务类:
package com.leo.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() { //打印当前name的内容
System.out.println("Current exec name is "+name); //以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()));
} public String getName() { return name;
} public void setName(String name) { this.name = name;
}
}四中启动类:
package com.leo.timer;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Timer;public class MyTimer { public static void main(String[] args){ //一.创建一个timer实例
Timer timer=new Timer(); //二.创建一个MyTimerTask实例
MyTimerTask myTimerTask=new MyTimerTask("No.1"); //三.通过timer定时频率调用myTImerTask的业务逻辑
// 既第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
* 如果当前时间是2017-10-21 23:59:57
* 则设置后的时间则为2017-10-22 00:00:00
*/
Calendar calendar=Calendar.getInstance();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sf.format(calendar.getTime()));
calendar.add(Calendar.SECOND,3); /**
* 1. schedule(task,time)
* 在时间等于或超过time的时候执行且仅执行一次task
* 如在2017-10-22 00:00:00 执行一次task:打印任务的名字
*/
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
/**
* 2. schedule(task,time,period)
* 时间等于或超过time时首次执行task
* 之后每隔period毫秒重复执行一次task
* 如在2017-10-22 00:00:00 第一次执行task:打印任务的名字
* 之后每隔两秒执行一次task
*/
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
/**
* 3. schedule(task,delay)
* 等待delay毫秒后执行且仅执行一次task
* 如现在是2017-10-22 00:00:00
* 则在2017-10-22 00:00:01执行一次task::打印任务的名字
*/
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,1000);
/**
* 4. schedule(task,delay,period)
* 等待delay毫秒后首次执行task
* 如现在是2017-10-22 00:00:00
* 则在2017-10-22 00:00:01执行一次task::打印任务的名字
* 之后每隔两秒执行一次task
*/
myTimerTask.setName("schedule4");
timer.schedule(myTimerTask,calendar.getTime(),2000);
}
}参数: task-所要安排的任务
time-首次执行任务的时间
period-执行一次task的时间间隔,单位是毫秒
作用: 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task(和schedule的第二种用法是一样的)
参数: task-所要安排的任务
delay-执行任务前的延迟时间,单位是毫秒
period-执行一次task的时间间隔,单位是毫秒
作用: 等待delay毫秒后执行且仅执行一次task,之后每隔period毫秒重复执行一次task(和schedule的第四种用法是一样的)
代码:
//----------------scheduleAtFixedRate的用法-------------------------------
/**
* 1 . scheduleAtFixedRate(task,time,period)
* 时间等于或超过time时首次执行task
* 之后每隔period毫秒重复执行一次task
* 如在2017-10-22 00:00:00 第一次执行task:打印任务的名字
* 之后每隔两秒执行一次task
*/
//myTimerTask.setName("scheduleAtFixedRate1");
//timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
/**
* 2. scheduleAtFixedRate(task,delay,period)
* 等待delay毫秒后首次执行task
* 如现在是2017-10-22 00:00:00
* 则在2017-10-22 00:00:01执行一次task::打印任务的名字
* 之后每隔两秒执行一次task
*/
myTimerTask.setName("scheduleAtFixedRate2");
timer.scheduleAtFixedRate(myTimerTask,3000,2000);我们先来看Timer的其他重要函数,下一标题再具体讲解schedule和schedulAtFixedRate二者的不同
cancel:
作用:取消当前TimerTask里的任务
@Override
public void run() { if (count<3){ //打印当前name的内容
System.out.println("Current exec name is "+name); //以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()));
count++;
}else {
cancel();
System.out.println("Task cancel");
}
}scheduledExecutionTime():
作用:返回此任务最近实际执行的已安排执行的时间
cancel():
作用:终止此计时器,丢弃所有当前已安排的任务

purge():
作用:从此计时器的任务队列中移除所要已取消的任务
返回值:从队列中移除的任务数

"fixed-delay"如果第一次执行时间被delay了,随后的执行时间按上一次实际执行完成的时间点进行计算

console:

"fixed-rate"如果第一次执行时间被delay了,随后的执行时间按上一次实际执行完成的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步

console:

下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后

console:

下一次执行时间相对于上一次开始的时间点,因此执行的时间不会延后,因此存在并发性

console:

Timer有且仅有一个线程去执行定时任务,如果存在多个定时任务,且任务时间过长,会导致执行效果与预期不符


console:

同样scheduleAtFixedRate也不能解决并发问题:

如果TimerTask抛出RuntimeException,Timer会停止所有任务的执行
1.对时效性要求较高的多任务并发作业
2.对复杂的任务的调度
如果想要满足以上功能,需用到Quartz
Timer类的purge()函数 从此计时器的任务队列中移除所有已取消的任务
返回值为从队列中移除的任务数
Timer类的cancel() 终止计时器,丢弃所有已安排的任务
接上一笔记函数
另一重要函数
TimerTask类的函数
cancel()取消当前TimerTask里的任务