所有分类
  • 所有分类
  • 未分类

Java–Timer–使用

简介

本文用示例介绍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)和schedule方法类似,只是错过的任务会被继续执行
public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)和schedule方法类似,只是错过的任务会被继续执行
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, 1000l);
}

无限循环调度

定时任务每隔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, 1000l);

}

scheduleAtFixedRate 与 schedule 区别

scheduleAtFixedRate和schedule 的唯一区别就是, schedule 会将错过执行的定时任务丢弃, 而scheduleAtFixedRate 则会补上。

测试用例

public static void main(String[] args) {

        TimerTask timerTask = new TimerTask() {

            private int times = 0;
            @Override
            public void run() {

                try {

                    if(times++ ==3){
                        this.cancel();
                    }

                    System.out.printf("planExecTime:%s, now:%s, times:%s\n", new Date(scheduledExecutionTime()), new Date(), times);
                    Thread.sleep(3000);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };

        Timer timer = new Timer("myTimer");
        timer.schedule(timerTask, nextMinute(), 1000);
    }

    private static Date nextMinute(){

        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.MINUTE, 1);

        calendar.add(Calendar.SECOND, -calendar.get(Calendar.SECOND));

        return calendar.getTime();

    }

scheduleAtFixedRate 调度结果

从输出结果上来看, 定时任务计划执行时间与实际执行时间只有第一次一致,其它都不一致。 在定时任务执行的时间内,本应该执行的定时任务会依次被执行。

planExecTime:Sun Mar 31 18:03:00 CST 2019, now:Sun Mar 31 18:03:00 CST 2019, times:1
planExecTime:Sun Mar 31 18:03:01 CST 2019, now:Sun Mar 31 18:03:03 CST 2019, times:2
planExecTime:Sun Mar 31 18:03:02 CST 2019, now:Sun Mar 31 18:03:06 CST 2019, times:3
planExecTime:Sun Mar 31 18:03:03 CST 2019, now:Sun Mar 31 18:03:09 CST 2019, times:4

schedule 调度结果

从输出结果上可以看出, 计划执行时间和实际执行时间一致. 虽然笔者的调度时间为每隔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
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录