Java多线程学习(七)——定时器Timer

2019-11-12 19:49:04 浏览数 (2)

定时器Timer

在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。

schedule(TimeTask, Date)方法

执行任务的时间晚于当前时间

代码语言:javascript复制
publicclassMytask{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:" LocalDateTime.now());
Timer timer = newTimer();
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);
Date date = calendar.getTime();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("任务执行了,时间为:"  LocalDateTime.now());
}
}, date);
}
}
//输出
当前时间为:2019-06-25T07:46:41.911
任务执行了,时间为:2019-06-25T07:46:51.916

可以看到,当任务结束,进程依然处于挂起状态,创建一个Timer就启动一个新的线程,这个新的线程并不是守护线程,一直在运行。

代码语言:javascript复制
Timer timer = newTimer(true);

将其改为守护进程后发现任务并没有执行直接结束了,这是因为主进程已经结束。

如果任务早于当前时间则立即执行任务。

Timer中允许有多个TimerTask任务运行

TimerTask是以队列的方式一个一个被顺序的执行,所以执行时间可能和预期时间不一致,因为前面的任务有可能小号的时间长,所以后面的任务的运行时间也被延后。

schedule(TimeTask, Date, long)

该方法作用是指定日期之后按指定的间隔时间,无限的循环执行某一任务。

计划时间晚于当前时间

代码语言:javascript复制
{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:"  LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 5);
Date date = calendar.getTime();
System.out.println("计划时间为:"  date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("任务执行了,时间为:"  LocalDateTime.now());
}
}, date, 4000);
}
}
//输出
当前时间为:2019-06-25T08:02:31.533
计划时间为:TueJun2508:02:36 CST 2019
任务执行了,时间为:2019-06-25T08:02:36.537
任务执行了,时间为:2019-06-25T08:02:40.538
任务执行了,时间为:2019-06-25T08:02:44.539
任务执行了,时间为:2019-06-25T08:02:48.540
任务执行了,时间为:2019-06-25T08:02:52.540
任务执行了,时间为:2019-06-25T08:02:56.540
任务执行了,时间为:2019-06-25T08:03:00.541

可以看到任务每个4秒执行一次并且是无限循环的。

计划时间早于当前时间时候,任务会立即执行直到时间追赶上来为止。

Timertask()的cancel()方法

cancel方法作用是将自己从任务队列中清除。其他任务不受影响。

代码语言:javascript复制
publicclassMyTask3{
publicstaticvoid main(String[] args){
System.out.println("当前时间为:"  LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 5);
Date date = calendar.getTime();
System.out.println("计划时间为:"  date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("A run timer = "  LocalDateTime.now());
this.cancel();
System.out.println("A 将自己cancel了");
}
}, date, 2000);
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("B run timer = "  LocalDateTime.now());
}
}, date, 2000);
}
}
// 输出
当前时间为:2019-06-25T08:12:00.516
计划时间为:TueJun2508:12:05 CST 2019
A run timer = 2019-06-25T08:12:05.520
A 将自己cancel了
B run timer = 2019-06-25T08:12:05.520
B run timer = 2019-06-25T08:12:07.521
B run timer = 2019-06-25T08:12:09.521
B run timer = 2019-06-25T08:12:11.522

Timer类的cancel()方法

作用是将任务队列中的全部任务进行清空。

scheduleAtFixedRate与schedule方法

scheduleAtFixedRate方法具有追赶的特性。将两个时间段内的时间所对应的Task任务被“补充性”的执行,这就是Task任务的追赶特性。

代码语言:javascript复制
publicclassMyTask4{
publicstaticvoid main(String[] args){
System.out.println("现在执行时间:"  LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND)-20);
Date date = calendar.getTime();
System.out.println("计划执行时间:"  date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("开始:" LocalDateTime.now());
System.out.println("  结束:" LocalDateTime.now());
}
}, date, 2000);
}
}
//输出
现在执行时间:2019-06-25T08:25:38.055
计划执行时间:TueJun2508:25:18 CST 2019
开始:2019-06-25T08:25:38.067
结束:2019-06-25T08:25:38.067
开始:2019-06-25T08:25:40.067
结束:2019-06-25T08:25:40.067
开始:2019-06-25T08:25:42.067
结束:2019-06-25T08:25:42.067
开始:2019-06-25T08:25:44.068
结束:2019-06-25T08:25:44.068

时间“08:25:18”到“08:25:38”中所对应的Task都被取消不执行了,这就是Task的不追赶。

代码语言:javascript复制
publicclassMyTask4{
publicstaticvoid main(String[] args){
System.out.println("现在执行时间:"  LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND)-20);
Date date = calendar.getTime();
System.out.println("计划执行时间:"  date);
Timer timer = newTimer();
        timer.schedule(newTimerTask() {
@Override
publicvoid run() {
System.out.println("开始:" LocalDateTime.now());
System.out.println("  结束:" LocalDateTime.now());
}
}, date, 2000);
}
}
//输出
现在执行时间:2019-06-25T08:25:38.055
计划执行时间:TueJun2508:25:18 CST 2019
开始:2019-06-25T08:25:38.067
结束:2019-06-25T08:25:38.067
开始:2019-06-25T08:25:40.067
结束:2019-06-25T08:25:40.067
开始:2019-06-25T08:25:42.067
结束:2019-06-25T08:25:42.067
开始:2019-06-25T08:25:44.068
结束:2019-06-25T08:25:44.068

scheduleAtFixed会将这段时间内所有的任务都执行一遍。

0 人点赞