简介
本文用示例介绍Java中的定时器Timer的用法。
方法大全
默认情况下,Timer 创建的线程为用户线程, 如果想让其为守护进程的话, 创建时需要设置isDaemon 为true。
构造方法
| 方法 | 方法描述 |
| public Timer(String name) | 构造方法,创建定时器,并指定线程名称。以定时调度线程为用户线程 |
| public Timer(boolean isDaemon) | 构造方法,创建定时器,isDaemon 设置为true时表示以守护线程执行 |
| public Timer(String name, boolean isDaemon) | 构造方法,创建定时器,并指定线程名称。isDaemon 设置为true时表示以守护线程执行 |
其他方法
| 方法 | 方法描述 |
| public void schedule(TimerTask task, long delay) | 只调度一次,delay毫秒之后执行。 |
| public void schedule(TimerTask task, Date time) | 只调度一次,在具体时刻time 执行。 |
| public void schedule(TimerTask task, long delay, long period) | 循环调度,在delay毫秒之后开始,每隔period毫秒执行一次。(如果到点有任务还没结束,则放弃本次执行)。 |
| public void schedule(TimerTask task, Date firstTime, long period) | 循环调度,在时刻firstTime开始,每隔period毫秒执行一次。(如果到点有任务还没结束,则放弃本次执行)。 |
| public void scheduleAtFixedRate(TimerTask task, long delay, long period) | 循环调度,在delay毫秒之后开始,每隔period毫秒执行一次。(如果到点有任务还没结束,不放弃本次执行)。 |
| public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) | 循环调度,在时刻firstTime开始,每隔period毫秒执行一次。(如果到点有任务还没结束,不放弃本次执行)。 |
| public int purge() | 清理所有已取消状态的TimerTask |
| public void cancel() | 取消所有调度 |
实例
延时调度一次
程序启动3秒之后, 执行一次
public static void main(String[] args) throws InterruptedException {
// 创建定时器
Timer timer = new Timer("myTimer");
// 创建定时任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(LocalDateTime.now() + "-hello");
}
};
// 添加调度
timer.schedule(timerTask ,3000);
}
定时调度一次
定时任务在下一分钟00秒时执行一次
public static void main(String[] args) throws InterruptedException {
// 创建定时器
Timer timer = new Timer("myTimer");
// 创建定时任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(LocalDateTime.now() + "-hello");
}
};
Date nextMinute = nextMinute();
System.out.println("now:" + new Date() + ", execute:" + nextMinute);
// 添加调度
timer.schedule(timerTask ,nextMinute);
}
// 获取下一分钟的时间
private static Date nextMinute(){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 1);
calendar.add(Calendar.SECOND, -calendar.get(Calendar.SECOND));
return calendar.getTime();
}
循环调度n次
定时任务每隔1秒中执行一次, 执行n次后停止
public static void main(String[] args) throws InterruptedException {
// 创建定时器
Timer timer = new Timer("myTimer");
// 创建定时任务
TimerTask timerTask = new TimerTask() {
private int times = 0;
@Override
public void run() {
// 执行5次后, 取消任务
if(++times ==5 ){
this.cancel();
}
System.out.println(LocalDateTime.now() + "-hello, times:" + times);
}
};
// 添加调度
timer.schedule(timerTask ,0, 1000);
}
无限循环调度
定时任务每隔1秒中执行一次, 无限循环
public static void main(String[] args) throws InterruptedException {
// 创建定时器
Timer timer = new Timer("myTimer");
// 创建定时任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(LocalDateTime.now() + "-hello");
}
};
// 添加调度
timer.schedule(timerTask ,0, 1000);
}
scheduleAtFixedRate 与 schedule 区别
scheduleAtFixedRate和schedule 的唯一区别就是, schedule 会将错过执行的定时任务丢弃, 而scheduleAtFixedRate 则会补上。
测试用例
package com.example.a;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Demo{
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
try {
System.out.printf("planTime:%s,now:%s\n",
new Date(scheduledExecutionTime()),
new Date());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Timer timer = new Timer("myTimer");
timer.scheduleAtFixedRate(timerTask, 0, 1000);
// timer.schedule(timerTask, 0, 1000);
}
}
从结果上看, 定时任务计划执行时间与实际执行时间只有第一次一致,其它都不一致。 在定时任务执行的时间内,本应该执行的定时任务会依次被执行。
planTime:Sun Jul 27 18:01:14 CST 2025,now:Sun Jul 27 18:01:15 CST 2025 planTime:Sun Jul 27 18:01:15 CST 2025,now:Sun Jul 27 18:01:18 CST 2025 planTime:Sun Jul 27 18:01:16 CST 2025,now:Sun Jul 27 18:01:21 CST 2025 planTime:Sun Jul 27 18:01:17 CST 2025,now:Sun Jul 27 18:01:24 CST 2025 planTime:Sun Jul 27 18:01:18 CST 2025,now:Sun Jul 27 18:01:27 CST 2025
不用担心,队列里一直是只有一个任务在,看断点:

从结果上看,,计划执行时间和实际执行时间一致,虽然笔者的调度时间为每隔1秒, 但是定时任务执行需要3秒的时间。 在定时任务执行期间,本应该有的调度全部丢弃。
planExecTime:Sun Mar 31 18:01:00 CST 2019, now:Sun Mar 31 18:01:00 CST 2019, times:1 planExecTime:Sun Mar 31 18:01:03 CST 2019, now:Sun Mar 31 18:01:03 CST 2019, times:2 planExecTime:Sun Mar 31 18:01:06 CST 2019, now:Sun Mar 31 18:01:06 CST 2019, times:3 planExecTime:Sun Mar 31 18:01:09 CST 2019, now:Sun Mar 31 18:01:09 CST 2019, times:4

请先 !