目录
一、方法schedule(TimerTask task, Date time)——指定日期执行一次任务
二、方法schedule(TimerTask task,Date firstTime,long period)——按时间周期重复执行
三、TimerTask类的cancel()方法和Timer的cancel()方法——任务移除
四、方法schedule(TimerTask task,long delay)——延迟执行
五、schedule不追赶和scheduleAtFixedRate追赶
Timer类的主要作用是设置计划任务,但封装任务的类却是TimerTask类,执行计划任务的代码要放入TimerTask的子类中,因为TimeTask是一个抽象类。
一、方法schedule(TimerTask task, Date time)——指定日期执行一次任务
schedule(TimerTask task, Date time)方法摘取
public abstract class TimerTask implements Runnable {
}
1、TimerTask类为抽象类,实现了Runnable接口,主要用来创建一个新的线程执行任务。
2、Date time 为执行任务的日期,如果该日期早于当前时间,那么程序启动后,任务会立即执行。
3、创建一个Timer就是启动一个新线程,其中创建Timer时传true,可以设置此线程为守护线程。
// 设置定时器开启的线程为守护线程
private static Timer timer = new Timer(true);
4、一个Timer可以执行多个TimerTask任务,TimerTask任务以队列的方式一个个被顺序执行,当前面任务执行时间较长时,会使得后边任务的运行时间也会被延迟,从而出现执行时间于预期时间不一致的情况。
测试代码:
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间2s
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyTaskB extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
System.out.println("MytaskB任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 计划时间早于当前时间,任务会被立即执行
timer.schedule(taskA,parse);
// B任务会收到A任务执行时间的影响,执行时间延迟,从而使实际执行时间与预计执行时间不一致
timer.schedule(taskB,parse);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
执行结果:
二、方法schedule(TimerTask task,Date firstTime,long period)——按时间周期重复执行
该方法的作用是在指定的日期之后,按指定的时间间隔周期性地无限循环地执行某一任务。
TimerTask task 需要执行的任务
Date firstTime 执行任务开始时间,同样的,如过此时间早于当前时间,任务会被立即执行,反之,会达到未来执行的效果。
long period 任务循环执行的间隔时间周期
注:后边执行任务仍然会受到前边执行任务的影响,出现任务执行延时。
测试代码:
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间5s,大于规定的任务执行时间间隔周期,那么任务的执行会按这个延迟时间间隔来执行
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyTaskB extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
System.out.println("MytaskB任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 计划时间早于当前时间,任务会被立即执行
timer.schedule(taskA,parse,4000);
// B任务会收到A任务执行时间的影响,执行时间延迟,从而使实际执行时间与预计执行时间不一致
timer.schedule(taskB,parse,4000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
截取测试结果:
三、TimerTask类的cancel()方法和Timer的cancel()方法——任务移除
TimerTask类的cancel()方法是将自身从任务队列中移除,其他任务不受影响。
Timer的cancel()方法是清除全部任务,并使进程终止。
测试代码:
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyTaskB extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
System.out.println("MytaskB任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// B任务被执行一次后移除
this.cancel();
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 计划时间早于当前时间,任务会被立即执行
timer.schedule(taskA,parse,4000);
// B任务会收到A任务执行时间的影响,执行时间延迟,从而使实际执行时间与预计执行时间不一致
timer.schedule(taskB,parse,4000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
测试结果:
执行TimerTask类的cancel()方法,只会移除当前单个执行任务,并不会影响其他定时任务的执行,接下来改变调用对象,使用Timer的cancel()方法,我们将看到所有任务都将被终止。
测试代码:
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyTaskB extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
System.out.println("MytaskB任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 使用定时器的移除方法,此时会终止所有任务!!!
timer.cancel();
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 计划时间早于当前时间,任务会被立即执行
timer.schedule(taskA,parse,4000);
// B任务会收到A任务执行时间的影响,执行时间延迟,从而使实际执行时间与预计执行时间不一致
timer.schedule(taskB,parse,4000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
测试结果:
四、方法schedule(TimerTask task,long delay)——延迟执行
方法schedule(TimerTask task,long delay),是以当前时间为参考,然后按照指定延迟时间执行一次任务。
方法schedule(TimerTask task,long delay,long period),以当前时间为参考,按照指定延迟时间,开始周期性的循环执行任务。
测试代码:
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyTaskB extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
System.out.println("MytaskB任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延迟执行
timer.schedule(taskA,4000,4000);
// B任务会收到A任务执行时间的影响,执行时间延迟,从而使实际执行时间与预计执行时间不一致
timer.schedule(taskB,4000,4000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
测试结果:
五、schedule不追赶和scheduleAtFixedRate追赶
schedule不追赶,执行时间早于当前时间,程序会以当前时间为开始时间执行任务,前边没有被执行的任务,不再执行。
scheduleAtFixedRate追赶,执行时间早于当前时间,程序会以当前时间为开始时间执行任务,前边没有被执行的任务,全部会被补充执行。
public class MyService {
// 创建一个定时器
private static Timer timer = new Timer();
public static class MyTaskA extends TimerTask{
@Override
public void run() {
// 开启一个线程执行定时任务
try {
System.out.println("MyTaskA任务执行,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// 延长执行时间
Thread.sleep(1000);
System.out.println("MyTaskA任务结束,时间为:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// schedule
timer.schedule(taskA,parse,3000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
测试结果:
接下来把执行代码换成:timer.scheduleAtFixedRate(taskA,parse,4000);
public static void main(String[] args) {
// 创建多个执行任务
MyTaskA taskA = new MyTaskA();
try {
Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-31 14:42:00");
System.out.println("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
// schedule
timer.scheduleAtFixedRate(taskA,parse,3000);
} catch (ParseException e) {
e.printStackTrace();
}
}
测试结果: