JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。Timer类的主要作用就是设置计划任务,但封装任务的是TimerTask类,执行计划任务的代码要放入TimerTask的子类中。
1.schedule(TimerTask task,Date timer);
MyTask
public class MyTask extends TimerTask{
@Override
public void run() {
System.out.println("任务执行了,时间为:" + new Date());
try {
//没必要睡眠,写这个是为了验证后面的东西
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Test1
public class Test1 {
public static void main(String[] args) {
System.out.println("当前时间为:" + new Date());
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,10);
Date date = calendar.getTime();
MyTask myTask = new MyTask();
Timer timer = new Timer();
//10秒后执行,data为执行时间
timer.schedule(myTask,date);
}
}
执行后可以看到程序还在运行可以通过查看Timer源码看到,Timer的构造方法开启了一个线程,非守护线程,所以会一直运行
Timer的特性
1.执行任务的时间晚于当前时间-在未来执行
2.计划时间早于当前时间-提前运行
3.Timer中允许有多个Timer任务,它以队列的方式一个一个被顺序性的执行,所以执行时间有可能不一致,比如前面的任务消耗时间很长,则后面的任务运行时间也被延后
MyTaskA
public class MyTaskA extends TimerTask{
@Override
public void run() {
try {
System.out.println("A start 的时间 :" + new Date());
Thread.sleep(20000);
System.out.println("A end 的时间 :" + new Date());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
MyTaskB
public class MyTaskB extends TimerTask {
@Override
public void run() {
System.out.println("B start 的时间 :" + new Date());
System.out.println("B end 的时间 :" + new Date());
}
}
Test2
public class Test2 {
public static void main(String[] args) {
System.out.println("当前时间为 :" + new Date());
Calendar calendar1 = Calendar.getInstance();
Date runDateA = calendar1.getTime();
System.out.println("A 计划执行的时间为 :" + runDateA);
Calendar calendar2 = Calendar.getInstance();
calendar2.add(Calendar.SECOND,10);
Date runDateB = calendar2.getTime();
System.out.println("B 计划执行的时间为 :" + runDateB);
MyTaskA myTaskA = new MyTaskA();
MyTaskB myTaskB = new MyTaskB();
Timer timer = new Timer();
timer.schedule(myTaskA,runDateA);
timer.schedule(myTaskB,runDateB);
}
}
运行结果
本该10秒后执行的B计划,由于A计划执行了20秒,所以不得不20秒后再执行
2.schedule(TimerTask task,Date firstTime,long period);
在指定的日期后按指定的时间间隔周期,无线循环执行某一任务。特性如下
1.计划时间晚于当前时间-在未来执行
2.计划时间早于当前时间-提前运行
3.由于某一任务执行时间过长,导致超过循环时间long,则任务延迟执行
4.cancel()方法的作用是将自身从任务队列中移除,移除以后将不再进行循环
5.Timer的cancel()清除队列中所有任务
3.schedule(TimerTask task,long delay);
以执行该方法当前的时间为参考时间,在此时间基础上延迟指定毫秒数后执行一次TimerTask任务
3.schedule(TimerTask taks,long delay,long period);
延迟指定好秒后执行,并以某一间隔循环执行
4.scheduleAtFixedRate(TimerTask task,Date firstTimer,long period)
和schedule一样都是按顺序执行,所以不用考虑非线程安全的情况,区别在于有没有追赶性,如果开始时间在n秒前,则scheduleAtFixedRate会无视period,连续执行,直到追赶到了n秒