简介
本文用示例介绍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
请先
!