资讯专栏INFORMATION COLUMN

Java定时器Timer

shiina / 2382人阅读

摘要:定时器概述主要用于线程里指定时间或周期运行任务。同时指定关联线程的名称和是否作为。以当前时间为基准,延迟指定的毫秒后,再按指定的时间间隔地无限次数的执行任务。使用示例执行结果说明指定的之间早于当前时间,则立刻执行。

Java定时器Timer 概述

主要用于Java线程里指定时间或周期运行任务。Timer是线程安全的,但不提供实时性(real-time)保证。

构造函数 Timer()

默认构造函数。

Timer(boolean)

指定关联线程是否作为daemon线程。

Timer(String)

指定关联线程的名称。

Timer(String, boolean)

同时指定关联线程的名称和是否作为daemon。

schdule方法 schedule(TimerTask task, long delay)

以当前时间为基准,延迟指定的毫秒后执行一次TimerTask任务。

schedule(TimerTask task, Date time)

在指定的日期执行一次TimerTask任务。

如果日期time早于当前时间,则立刻执行。

使用示例

public class Demo {
    private static Timer timer = new Timer();

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Run Time:" + new Date().toString());
        }
    }
    
    public static void main(String[] args) {
        try {
            MyTask task = new MyTask();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = "2016-12-27 14:36:00";
            Date date = sdf.parse(dateStr);
            System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
            timer.schedule(task, date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

执行结果

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 21:28:04 CST 2016
Run Time:Tue Dec 27 21:28:04 CST 2016

说明是立刻执行。

schedule(TimerTask task, long delay, long period)

以当前时间为基准,延迟指定的毫秒后,再按指定的时间间隔地无限次数的执行TimerTask任务。(fixed-delay execution)

使用示例

public class Demo {
    private static Timer timer = new Timer();

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Run Time: " + new Date().toString());
        }
    }

    public static void main(String[] args) {
        MyTask task = new MyTask();
        System.out.println("Now Time: " + new Date().toString());
        timer.schedule(task, 3000, 5000);
    }
}

执行结果

Now Time: Tue Dec 27 21:34:59 CST 2016
Run Time: Tue Dec 27 21:35:02 CST 2016
Run Time: Tue Dec 27 21:35:07 CST 2016
Run Time: Tue Dec 27 21:35:12 CST 2016
Run Time: Tue Dec 27 21:35:17 CST 2016

说明以当前基准时间延迟3秒后执行一次,以后按指定间隔时间5秒无限次数的执行。

schedule(TimerTask task, Date firstTime, long period)

在指定的日期之后,按指定的时间间隔地无限次数的执行TimerTask任务。(fixed-delay execution)

如果日期firstTime早于当前时间,则立刻执行,且不执行在时间差内的任务。

使用示例

public class Demo {
    private static Timer timer = new Timer();

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Run Time:" + new Date().toString());
        }

        public static void main(String[] args) {
            try {
                MyTask task = new MyTask();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateStr = "2016-12-27 14:36:00";
                Date date = sdf.parse(dateStr);
                System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
                timer.schedule(task, date, 3000);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }
}

执行结果

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 21:43:30 CST 2016
Run Time:Tue Dec 27 21:43:30 CST 2016
Run Time:Tue Dec 27 21:43:33 CST 2016
Run Time:Tue Dec 27 21:43:36 CST 2016

说明指定的之间早于当前时间,则立刻执行,不会补充时间差内的任务

scheduleAtFixedRate方法 scheduleAtFixedRate(TimerTask task, long delay, long period)

以当前时间为基准,延迟指定的毫秒后,再按指定的时间间隔周期性地无限次数的执行TimerTask任务。(fixed-rate execution)

使用示例

public class Demo {
    private static Timer timer = new Timer();

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Run Time: " + new Date().toString());
        }
    }

    public static void main(String[] args) {
        MyTask task = new MyTask();
        System.out.println("Now Time: " + new Date().toString());
        timer.scheduleAtFixedRate(task, 3000, 5000);
    }
}

执行结果

Now Time: Tue Dec 27 21:58:03 CST 2016
Run Time: Tue Dec 27 21:58:06 CST 2016
Run Time: Tue Dec 27 21:58:11 CST 2016
Run Time: Tue Dec 27 21:58:16 CST 2016
Run Time: Tue Dec 27 21:58:21 CST 2016

说明以当前基准时间延迟3秒后执行一次,以后按指定间隔时间5秒无限次数的执行。

scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

在指定的日期之后,按指定的时间间隔周期性地无限次数的执行TimerTask任务。(fixed-rate execution)

如果日期firstTime早于当前时间,则立即执行,并补充性的执行在时间差内的任务。

使用示例

public class Demo {
    private static Timer timer = new Timer();

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("Run Time:" + new Date().toString());
        }

        public static void main(String[] args) {
            try {
                MyTask task = new MyTask();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateStr = "2016-12-27 22:02:00";
                Date date = sdf.parse(dateStr);
                System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
                timer.scheduleAtFixedRate(task, date, 5000);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }
}

执行结果

Date = Tue Dec 27 22:02:00 CST 2016 NowTime = Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:54 CST 2016
Run Time:Tue Dec 27 22:02:55 CST 2016
Run Time:Tue Dec 27 22:03:00 CST 2016
Run Time:Tue Dec 27 22:03:05 CST 2016

说明指定的之间早于当前时间,则立刻执行。

在时间22:02:00--22:02:54内大约有11个5秒间隔,则优先补充性的执行在时间差内的任务,然后在22:02:55补充完毕(执行12次。ps:0-55秒区间段内首位都算上,正好触发12次),此后每隔5秒执行一次定时任务。

执行任务延时对比之 schedule 和 scheduleAtFixedRate schedule不延时

使用示例

public class Demo {
    private static Timer timer = new Timer();
    private static int runCount = 0;

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            try {
                System.out.println("Begin Run Time: " + new Date().toString());
                Thread.sleep(3000);
                System.out.println("End Run Time: " + new Date().toString());
                runCount++;
                if (runCount == 3) {
                    timer.cancel();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        try {
            MyTask task = new MyTask();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = "2016-12-27 14:36:00";
            Date date = sdf.parse(dateStr);
            System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
            timer.schedule(task, date, 5000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 14:36:00 CST 2016 NowTime = Tue Dec 27 22:23:37 CST 2016
Begin Run Time: Tue Dec 27 22:23:37 CST 2016
End Run Time: Tue Dec 27 22:23:40 CST 2016
Begin Run Time: Tue Dec 27 22:23:42 CST 2016
End Run Time: Tue Dec 27 22:23:45 CST 2016
Begin Run Time: Tue Dec 27 22:23:47 CST 2016
End Run Time: Tue Dec 27 22:23:50 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:42:00 CST 2016 NowTime = Tue Dec 27 22:41:54 CST 2016
Begin Run Time: Tue Dec 27 22:42:00 CST 2016
End Run Time: Tue Dec 27 22:42:03 CST 2016
Begin Run Time: Tue Dec 27 22:42:05 CST 2016
End Run Time: Tue Dec 27 22:42:08 CST 2016
Begin Run Time: Tue Dec 27 22:42:10 CST 2016
End Run Time: Tue Dec 27 22:42:13 CST 2016

Process finished with exit code 0

不管早还是晚于基准时间,都不进行补偿,下一次任务的执行时间参考的是上一次任务的开始时间点来计算。

schedule延时

使用示例

public class Demo {
    private static Timer timer = new Timer();
    private static int runCount = 0;

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            try {
                System.out.println("Begin Run Time: " + new Date().toString());
                Thread.sleep(5000);
                System.out.println("End Run Time: " + new Date().toString());
                runCount++;
                if (runCount == 3) {
                    timer.cancel();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        try {
            MyTask task = new MyTask();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = "2016-12-27 22:42:00";
            Date date = sdf.parse(dateStr);
            System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
            timer.schedule(task, date, 3000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 22:42:00 CST 2016 NowTime = Tue Dec 27 22:45:17 CST 2016
Begin Run Time: Tue Dec 27 22:45:17 CST 2016
End Run Time: Tue Dec 27 22:45:22 CST 2016
Begin Run Time: Tue Dec 27 22:45:22 CST 2016
End Run Time: Tue Dec 27 22:45:27 CST 2016
Begin Run Time: Tue Dec 27 22:45:27 CST 2016
End Run Time: Tue Dec 27 22:45:32 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:47:00 CST 2016 NowTime = Tue Dec 27 22:46:27 CST 2016
Begin Run Time: Tue Dec 27 22:47:00 CST 2016
End Run Time: Tue Dec 27 22:47:05 CST 2016
Begin Run Time: Tue Dec 27 22:47:05 CST 2016
End Run Time: Tue Dec 27 22:47:10 CST 2016
Begin Run Time: Tue Dec 27 22:47:10 CST 2016
End Run Time: Tue Dec 27 22:47:15 CST 2016

Process finished with exit code 0

不管早还是晚于当前基准时间,都不进行补偿,下一次任务的执行时间都是参考上一次任务结束的时间点来计算。

scheduleAtFixedRate不延时

使用示例

public class Demo {
    private static Timer timer = new Timer();
    private static int runCount = 0;

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            try {
                System.out.println("Begin Run Time: " + new Date().toString());
                Thread.sleep(3000);
                System.out.println("End Run Time: " + new Date().toString());
                runCount++;
                if (runCount == 1000) {
                    timer.cancel();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            MyTask task = new MyTask();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = "2016-12-27 22:51:42";
            Date date = sdf.parse(dateStr);
            System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
            timer.scheduleAtFixedRate(task, date, 5000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 22:51:42 CST 2016 NowTime = Tue Dec 27 22:51:57 CST 2016
Begin Run Time: Tue Dec 27 22:51:57 CST 2016
End Run Time: Tue Dec 27 22:52:00 CST 2016
Begin Run Time: Tue Dec 27 22:52:00 CST 2016
End Run Time: Tue Dec 27 22:52:03 CST 2016
Begin Run Time: Tue Dec 27 22:52:03 CST 2016
End Run Time: Tue Dec 27 22:52:06 CST 2016
Begin Run Time: Tue Dec 27 22:52:06 CST 2016
End Run Time: Tue Dec 27 22:52:09 CST 2016
Begin Run Time: Tue Dec 27 22:52:09 CST 2016
End Run Time: Tue Dec 27 22:52:12 CST 2016
Begin Run Time: Tue Dec 27 22:52:12 CST 2016
End Run Time: Tue Dec 27 22:52:15 CST 2016
Begin Run Time: Tue Dec 27 22:52:15 CST 2016
End Run Time: Tue Dec 27 22:52:18 CST 2016
Begin Run Time: Tue Dec 27 22:52:18 CST 2016
End Run Time: Tue Dec 27 22:52:21 CST 2016
Begin Run Time: Tue Dec 27 22:52:22 CST 2016
End Run Time: Tue Dec 27 22:52:25 CST 2016
Begin Run Time: Tue Dec 27 22:52:27 CST 2016
End Run Time: Tue Dec 27 22:52:30 CST 2016
Begin Run Time: Tue Dec 27 22:52:32 CST 2016
End Run Time: Tue Dec 27 22:52:35 CST 2016
Begin Run Time: Tue Dec 27 22:52:37 CST 2016
End Run Time: Tue Dec 27 22:52:40 CST 2016
Begin Run Time: Tue Dec 27 22:52:42 CST 2016
End Run Time: Tue Dec 27 22:52:45 CST 2016
Begin Run Time: Tue Dec 27 22:52:47 CST 2016
End Run Time: Tue Dec 27 22:52:50 CST 2016
Begin Run Time: Tue Dec 27 22:52:52 CST 2016
End Run Time: Tue Dec 27 22:52:55 CST 2016
Begin Run Time: Tue Dec 27 22:52:57 CST 2016
End Run Time: Tue Dec 27 22:53:00 CST 2016

Process finished with exit code 0

晚于当前基准时间

Date = Tue Dec 27 22:37:00 CST 2016 NowTime = Tue Dec 27 22:36:06 CST 2016
Begin Run Time: Tue Dec 27 22:37:00 CST 2016
End Run Time: Tue Dec 27 22:37:03 CST 2016
Begin Run Time: Tue Dec 27 22:37:05 CST 2016
End Run Time: Tue Dec 27 22:37:08 CST 2016
Begin Run Time: Tue Dec 27 22:37:10 CST 2016
End Run Time: Tue Dec 27 22:37:13 CST 2016

Process finished with exit code 0

不延时的情况下,当早于基准时间时,时间差内的执行任务未补偿完时,下一次执行任务的时间参考的是上一次执行任务的结束时间;一旦补偿完毕(注意粗体时间点),下一次执行任务的时间参考的是上一次执行任务的开始时间;当晚于基准时间时,下一次执行任务的时间参考的是上一次执行任务的开始时间。

scheduleAtFixedRate延时

使用示例

public class Demo {
    private static Timer timer = new Timer();
    private static int runCount = 0;

    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            try {
                System.out.println("Begin Run Time: " + new Date().toString());
                Thread.sleep(5000);
                System.out.println("End Run Time: " + new Date().toString());
                runCount++;
                if (runCount == 3) {
                    timer.cancel();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        try {
            MyTask task = new MyTask();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = "2016-12-27 22:28:00";
            Date date = sdf.parse(dateStr);
            System.out.println("Date = " + date.toString() + " NowTime = " + new Date().toString());
            timer.scheduleAtFixedRate(task, date, 3000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

执行结果

早于当前基准时间

Date = Tue Dec 27 23:01:00 CST 2016 NowTime = Tue Dec 27 23:01:19 CST 2016
Begin Run Time: Tue Dec 27 23:01:19 CST 2016
End Run Time: Tue Dec 27 23:01:24 CST 2016
Begin Run Time: Tue Dec 27 23:01:24 CST 2016
End Run Time: Tue Dec 27 23:01:29 CST 2016
Begin Run Time: Tue Dec 27 23:01:29 CST 2016
End Run Time: Tue Dec 27 23:01:34 CST 2016
Begin Run Time: Tue Dec 27 23:01:34 CST 2016
End Run Time: Tue Dec 27 23:01:39 CST 2016

晚于当前基准时间

Date = Tue Dec 27 22:28:00 CST 2016 NowTime = Tue Dec 27 22:27:55 CST 2016
Begin Run Time: Tue Dec 27 22:28:00 CST 2016
End Run Time: Tue Dec 27 22:28:05 CST 2016
Begin Run Time: Tue Dec 27 22:28:05 CST 2016
End Run Time: Tue Dec 27 22:28:10 CST 2016
Begin Run Time: Tue Dec 27 22:28:10 CST 2016
End Run Time: Tue Dec 27 22:28:15 CST 2016

Process finished with exit code 0

延时的情况下,即使是早于基准时间,由于延时效应,根本不可能补偿完毕时间差内的执行任务,故而在延时的情况下,下一次任务的执行时间都是参考上一次任务结束的时间来计算。

对比总结
执行任务不延时 执行任务延时
早于当前基准时间 schedule:下一次任务的执行时间参考的是上一次任务的开始时间来计算。 scheduleAtFixedRate:当早于基准时间时,时间差内的执行任务未补偿完时,下一次执行任务的时间参考的是上一次任务的结束时间;一旦补偿完毕,下一次执行任务的时间参考上一次任务的开始时间来计算。 二者一样。下一次任务的执行时间都是参考上一次任务的结束时间来计算。
晚于当前基准时间 二者一样。下一次任务的执行时间参考的是上一次任务的开始时间来计算。 二者一样。下一次任务的执行时间都是参考上一次任务的结束时间来计算。

注意:scheduleAtFixedRate示例中firstTime是有区别的,而结果证明是有补偿性操作的。

(END)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66446.html

相关文章

  • Java 定时任务系列(1)- Java原生支持

    摘要:第一次在指定时间点执行任务,之后每隔时间调用任务一次。定时器已启动每隔小时已经添加任务调度表这个方法在应用服务被移除,没有能力再接受请求的时候被调用。 1、普通thread实现 这是最常见的,创建一个thread,然后让它在while循环里一直运行着,通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,代码如下: public class Task1 { public ...

    melody_lql 评论0 收藏0
  • 慕课网_《Java定时任务调度工具详解之Timer篇》学习总结

    时间:2017年05月24日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:无个人学习源码:https://github.com/zccodere/s... 第一章:课程介绍 1-1 课程介绍 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务 在Java中的定时调度工具 Timer:小弟,能实现日常60%的定...

    wind5o 评论0 收藏0
  • Java时器Timer学习一

    摘要:类是一个定时任务类,该类实现了接口,而且是一个抽象类说明类是一个抽象类,由安排为一次执行或重复执行的任务。定时器实例有多种构造方法创建一个新计时器。 Timer 的定义 有且仅有一个后台线程对多个业务进行定时定频的调度。Timer 类可以保证多个线程可以共享单个 Timer 对象而无需进行外部同步,所以 Timer 类是线程安全的。 核心的两个类 java.util.Timer 和 ...

    AaronYuan 评论0 收藏0
  • Java时器Timer学习二

    摘要:代码实例获取当前时间按照指定的格式输出设置成秒之前的时间使用来执行控制台输出方法总结我们可以看到实际的效果是在启动执行的时候,会立马执行次就是为了追赶已经过去的秒。 方法名称 schedule() 和 scheduleAtFixedRate() 的区别 两种情况看区别 首次计划执行的时间早于当前时间 比如说:当前时间是 11:06, 但是首次计划执行的时间应该为: 11:00 任务执行...

    nemo 评论0 收藏0
  • Java定时任务调度工具】Timer

    摘要:笔记来源定时任务调度基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。可安排任务执行一次,或者定期重复执行。有且仅有一个后台线程对多个业务线程进行定时定频率的调度。 笔记来源:IMOOC Java Timer 定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。 Timer 定义 一种工具,线程用其安排以后在后台线程中执行的任务。可安排任...

    Rindia 评论0 收藏0
  • Java 多线程编程核心技术5—时器Timer

    摘要:如果执行任务的时间早于当前时间,则立即执行任务。其他任务不受影响。类中的方法作用是将任务队列中全部的任务进行清空。全部任务都被清除,并且进程被销毁。类中的方法有时并不一定会停止计划任务,而是正常执行。 Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类。 创建1个Tim...

    hqman 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<