admin管理员组

文章数量:1530842

Timer定时器,一般用来做延时任务或者循环定时执行的任务。

  • timer最常用的两个方法scheduleAtFixedRate与schedule。
        //schedule(TimerTask task, long delay);
        //延迟delay毫秒执行task
        timer.schedule(TimerTaskGet("1"),1000);
        //schedule(TimerTask task, Date time);
        //task在time执行
        timer.schedule(TimerTaskGet("2"),new Date());
        //schedule(TimerTask task, long delay, long period) ;
        //延迟delay毫秒后每隔period毫秒执行一次
        timer.schedule(TimerTaskGet("3"),0,1000);
        //schedule(TimerTask task, Date firstTime, long period) ;
        //从firstTime开始每隔period毫秒执行一次
        timer.schedule(TimerTaskGet("4"),time,1000);
        //scheduleAtFixedRate(TimerTask task, long delay, long period) ;
        //延迟delay毫秒后每隔period毫秒执行一次
        timer.scheduleAtFixedRate(TimerTaskGet("5"),0,1000);
        //scheduleAtFixedRate(TimerTask task, Date firstTime, long period) ;
        //从firstTime开始每隔period毫秒执行一次
        timer.scheduleAtFixedRate(TimerTaskGet("6"),time,1000);
  • 然后,scheduleAtFixedRate与schedule的区别。

        第一个区别,在定义固定时间开始执行时,如果定义的时间已经过去,及定义time变量是过去的时间,那么schedule从当前开始每隔period的时间执行,而scheduleAtFixedRate连续执行从time到现在应该执行的任务,直到当前时间再按照每隔period的时间执行。

下面测试:

        设置开始时间,延迟3秒后执行schedule

        Timer timer = new Timer();
        Date time = new Date();
        System.out.println("开始时间:"+time);

        try {
            Thread.sleep(3000);
        }catch (InterruptedException e){

        }

        timer.schedule(TimerTaskGet("4"),time,1000);

结果如下,隔三秒后按间隔时间执行。

开始时间:Thu Sep 06 15:51:20 CST 2018
4  Thu Sep 06 15:51:23 CST 2018
4  Thu Sep 06 15:51:24 CST 2018
4  Thu Sep 06 15:51:25 CST 2018
4  Thu Sep 06 15:51:26 CST 2018
4  Thu Sep 06 15:51:27 CST 2018

 

        设置开始时间,延迟3秒后执行scheduleAtFixedRate

        Timer timer = new Timer();
        Date time = new Date();
        System.out.println("开始时间:"+time);

        try {
            Thread.sleep(3000);
        }catch (InterruptedException e){

        }

        timer.scheduleAtFixedRate(TimerTaskGet("6"),time,1000);

结果如下,隔三秒后将之前三秒钟任务补齐,然后再按间隔时间执行任务。

开始时间:Thu Sep 06 15:57:17 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:21 CST 2018
6  Thu Sep 06 15:57:22 CST 2018
6  Thu Sep 06 15:57:23 CST 2018
6  Thu Sep 06 15:57:24 CST 2018
6  Thu Sep 06 15:57:25 CST 2018

        换句话说,如果指定开始执行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上。

第二个区别,从很多博主哪里看到的实例,任务时间大于间隔时间。

       timer.scheduleAtFixedRate(new TimerTask(){
            public void run() {
                System.out.println("execute task!"+ this.scheduledExecutionTime());
                System.out.println(new Date());
                try {
                    Thread.sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },startDate, 3 * 1000);

结果如下:

开始时间:Thu Sep 06 16:10:27 CST 2018
execute task!1536221427324
Thu Sep 06 16:10:27 CST 2018
execute task!1536221430324
Thu Sep 06 16:10:33 CST 2018
execute task!1536221433324
Thu Sep 06 16:10:39 CST 2018
execute task!1536221436324
Thu Sep 06 16:10:45 CST 2018

scheduleAtFixedRate调用时

scheduledExecutionTime()输出间隔只有3000毫秒

new Date()输出间隔为6秒

很多博主以scheduledExecutionTime()输出判断scheduleAtFixedRate方法是不管任务执行完没有,到达间隔时间就执行下一个。

schedule调用时

scheduledExecutionTime()输出间隔只有6000毫秒

new Date()输出间隔为6秒

很多博主以scheduledExecutionTime()输出判断schedule方法是执行完成后才开始判断间隔时间。

但是输出当前时间scheduleAtFixedRate与schedule是一样的,所以我怀疑scheduledExecutionTime()方法输出的应该类似于计划时间,而不是实际时间,scheduleAtFixedRate与schedule在用时上一样是任务完成后开始执行下一个任务。

求大神指教。

 

后附测试代码,比较乱。

package code;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;
import java.util.Timer;

/**
 * @Auther: Administrator
 * @Date: 2018/9/6 11:27
 * @Description:定时器使用方式
 */
public class TimerTest {

    public static void main(String[] args){

        Timer timer = new Timer();
        Timer timer2 = new Timer();
        Date time = new Date();
        System.out.println("开始时间:"+time);

/*        try {
            Thread.sleep(3000);
        }catch (InterruptedException e){

        }*/

        //schedule(TimerTask task, long delay);延迟delay毫秒执行task
        //timer.schedule(TimerTaskGet("1"),1000);
        //schedule(TimerTask task, Date time);task在time执行
        //timer.schedule(TimerTaskGet("2"),new Date());
        //schedule(TimerTask task, long delay, long period) ;
        //延迟delay毫秒后每隔period毫秒执行一次
        //timer.schedule(TimerTaskGet("3"),0,1000);
        //schedule(TimerTask task, Date firstTime, long period) ;
        //从firstTime开始每隔period毫秒执行一次
        //timer.schedule(TimerTaskGet("4"),time,1000);
        //scheduleAtFixedRate(TimerTask task, long delay, long period) ;
        //延迟delay毫秒后每隔period毫秒执行一次
        //timer.scheduleAtFixedRate(TimerTaskGet("5"),0,1000);

/*        try {
            Thread.sleep(5000);
            timer.cancel();
        }catch (InterruptedException e){

        }*/

        //scheduleAtFixedRate(TimerTask task, Date firstTime, long period) ;
        //从firstTime开始每隔period毫秒执行一次
        //timer2.scheduleAtFixedRate(TimerTaskGet("6"),time,1000);


/*        try {
            Thread.sleep(5000);
            timer2.cancel();
        }catch (InterruptedException e){

        }*/

        /*   schedule和scheduleAtFixedRate的区别
        如果指定开始执行的时间在当前系统运行时间之前,
        scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上
        scheduleAtFixedRate 效率总体上高于schedule
         */


        Date startDate = time;
        //Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask(){
            public void run() {
                System.out.println("execute task!"+ this.scheduledExecutionTime());
                System.out.println(new Date());
                try {
                    Thread.sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },startDate, 3 * 1000);

    }

    //获取时间任务  每一个task只能调用一次,所以必须每次都new一个
    public static TimerTask TimerTaskGet(String s){
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {

/*                try {
                    Thread.sleep(3000);
                }catch (InterruptedException e){

                }*/

                System.out.println(s+"  "+new Date());
            }
        };
        return timerTask;
    }

}

 

本文标签: 定时器疑问区别Timerschedule