文章目录
1 定时器Timer的使用
Timer
类的主要作用就是设置计划任务,但封装任务的类却是TimerTask
类。
1.1 schedule(TimerTask task, Date time)
在指定的日期执行一次某一任务。
- 执行任务的时间晚于当前时间——在未来执行
public class Test1 {
public static void main(String[] args) {
System.out.println("now the time is: " + new Date());
Calendar calendarRef = Calendar.getInstance();
calendarRef.add(Calendar.SECOND, 10);
Date runDate = calendarRef.getTime();
MyTask myTask = new MyTask();
Timer timer = new Timer();
timer.schedule(myTask, runDate);
}
}
class MyTask extends TimerTask {
@Override
public void run() {
System.out.println("start executing job at " + new Date());
}
}
上例中任务执行完毕后,进程还未销毁,可以看到编辑器呈红色状态。
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(String name) {
thread.setName(name);
thread.start();
}
创建一个Timer
就是启动1个新的线程,那么这个新启动的线程并不是守护线程,一直在运行。
-
计划早于当前时间——提前运行,启动时立即执行任务
-
Timer中允许有多个TimerTask任务
TimerTask
是以队列的方式一个一个顺序地执行,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也被延后。
1.2 schedule(TimerTask task, Date firstTime, long period)
在指定的日期之后按指定的间隔周期,无限循环地执行某一任务。
- 计划时间晚于当前时间——在未来执行
- 计划时间早于当前时间——提前运行
- 任务执行时间被延时——依延时时间定
TimerTask
类的cancel()
方法:将自身从任务队列中进行清除Timer
类的cancel()
方法:将任务队列中全部的任务清空Timer
的cancel()
方法注意事项:有时并不一定会停止计划任务,而是正常执行。原因是Timer
类中的cancel()
方法有时并没有争抢到queue
锁,则让TimerTask
类中的任务正常执行。
1.3 schedule(TimerTask task, long delay)
以当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask
任务
1.4 schedule(TimerTask task, long delay, long period)
以当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask
任务,再以某一间隔时间无限次数地执行某一任务。
1.5 具有追赶特性的scheduleAtFixedRate
方法schedule
和方法scheduleAtFixedRate
都会按顺序执行,所以不需要考虑非线程安全的问题,两者的主要区别只在于有没有追赶特性。
public class TimerTest9 {
public static void main(String[] args) {
MyTask myTask = new MyTask();
System.out.println("start executing time:" + new Date());
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20);
Date runDate = calendar.getTime();
System.out.println("expect to execute time:" + runDate);
Timer timer = new Timer();
timer.schedule(myTask, runDate, 2000);
// timer.scheduleAtFixedRate(myTask, runDate, 2000);
}
static class MyTask extends TimerTask {
@Override
public void run() {
System.out.println("begin timer=" + new Date());
System.out.println(" end timer=" + new Date());
}
}
}
schedule执行结果:
start executing time:Sat Dec 19 15:55:59 CST 2020
expect to execute time:Sat Dec 19 15:55:39 CST 2020
begin timer=Sat Dec 19 15:55:59 CST 2020
end timer=Sat Dec 19 15:55:59 CST 2020
begin timer=Sat Dec 19 15:56:01 CST 2020
end timer=Sat Dec 19 15:56:01 CST 2020
begin timer=Sat Dec 19 15:56:03 CST 2020
scheduleAtFixedRate执行结果:
start executing time:Sat Dec 19 16:05:16 CST 2020
expect to execute time:Sat Dec 19 16:04:56 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:16 CST 2020
end timer=Sat Dec 19 16:05:16 CST 2020
begin timer=Sat Dec 19 16:05:18 CST 2020
end timer=Sat Dec 19 16:05:18 CST 2020
追赶特性:将两个时间段内的时间所对应的任务“补充性”地执行。Sat Dec 19 16:04:56 CST 2020 ~ Sat Dec 19 16:05:16 CST 2020