Java定时任务调度工具

  • 什么是定时任务调度
    • 基于给定的时间点给定的时间间隔或者给定的执行次数自动执行的任务

Timer

简介

位于java.util.Timer包下

  • 有且仅有一个后台线程多个业务线程进行定时定频率的调度

  • 主要构件:Timer(后台执行线程) -定时调用-> TimerTask(业务线程)

  • Timer工具类详解

    image-20201024220628861

实战演练

  1. 实现自定义MyTimerTask并继承TimerTask

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package com.example.timer;

    import lombok.Data;

    import java.util.TimerTask;

    /**
    * @author jinglv
    * @date 2020/10/25
    */
    @Data
    public class MyTimerTask extends TimerTask {

    private String name;

    public MyTimerTask(String name) {
    this.name = name;
    }

    @Override
    public void run() {
    // 以yyyy-MM-dd HH:mm:ss的格式打印当前执行时间
    // 如2020-10-25 00:00:00
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 打印当前执行时间
    System.out.println("Current exec time is:" + simpleDateFormat.format(calendar.getTime()));
    // 打印当前name的内容
    System.out.println("Current exec name is: " + name);
    }
    }
  1. 实现自定义MyTimer,并进行定时任务的执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package com.example.timer;

    import java.util.Timer;

    /**
    * @author jinglv
    * @date 2020/10/25
    */
    public class MyTimer {

    public static void main(String[] args) {
    //1. 创建一个timer实例
    Timer timer = new Timer();
    //2. 创建一个MyTimerTask实例
    MyTimerTask myTimerTask = new MyTimerTask("No.1");
    //3.通过timer定时定频率调用myTimerTask的业务逻辑
    // 即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
    timer.schedule(myTimerTask, 2000L, 1000L);
    }
    }

Timer定时函数的用法

schedule的四种用法

  • schedule(task, time)

    • 参数

      • task-所要安排的任务
      • time-执行任务的时间
    • 作用

      • 在时间等于或超过time的时候执行且仅执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 在时间等于或超过time的时候执行且执行一次task, 如:在2020-10-26 14:30:00执行一次task,打印任务的名字
      myTimerTask.setName("schedule1");
      timer.schedule(myTimerTask, calendar.getTime());
      }
      }
  • schedule(task, time, period)

    • 参数

      • task-所要安排的任务
      • time-执行任务的时间
      • period-执行一次task的时间间隔,单位是毫秒
    • 作用:

      • 时间等于或超过time时首次执行task
      • 之后每隔period毫秒重复执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task, 如:在2020-10-26 14:30:00执行一次task,打印任务的名字,之后每隔两秒执行一次task
      myTimerTask.setName("schedule2");
      timer.schedule(myTimerTask, calendar.getTime(), 2000);
      }
      }
  • schedule(task, delay)

    • 参数

      • task-所要安排的任务
      • delay-执行任务前的延迟时间,单位是毫秒
    • 作用:

      • 等待delay毫秒后执行且仅执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 等待delay毫秒后执行且执行一次task,如:现在2020-10-26 14:30:00,则在2020-10-26 14:30:01执行一次task,打印任务的名字
      myTimerTask.setName("schedule3");
      timer.schedule(myTimerTask, 1000);
      }
      }
  • schedule(task, delay, period)

    • 参数:

      • task-所要安排的任务
      • delay-执行任务前的延迟时间,单位是毫秒
      • period-执行一次task的时间间隔,单位是毫秒
    • 作用:

      • 等待delay毫秒后首次执行行task
      • 之后每隔period毫秒重复执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task, 如:现在2020-10-26 14:30:00,则在2020-10-26 14:30:01执行一次task,打印任务的名字,之后每隔两秒执行一次
      myTimerTask.setName("schedule4");
      timer.schedule(myTimerTask, 1000, 2000);
      }
      }

scheduleAtFixedRate的两种用法

  • scheduleAtFixedRate(task, time, period)

    • 参数

      • task-所要安排的任务
      • time-执行任务的时间
      • period-执行一次task的时间间隔,单位是毫秒
    • 作用:

      • 时间等于或超过time时首次执行task
      • 之后每隔period毫秒重复执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task,如:在2020-10-26 14:30:00执行一次task,打印任务的名字,之后每隔两秒执行一次task
      myTimerTask.setName("scheduleAtFixedRate1");
      timer.scheduleAtFixedRate(myTimerTask, calendar.getTime(), 2000);
      }
      }
  • scheduleAtFixedRate(task, deplay, period)

    • 参数:

      • task-所要安排的任务
      • delay-执行任务前的延迟时间,单位是毫秒
      • period-执行一次task的时间间隔,单位是毫秒
    • 作用:

      • 等待delay毫秒后首次执行行task
      • 之后每隔period毫秒重复执行一次task
    • 代码示例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      package com.example.timer;

      import java.util.Timer;

      /**
      * @author jinglv
      * @date 2020/10/25
      */
      public class MyTimer {

      public static void main(String[] args) {
      // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      System.out.println(simpleDateFormat.format(calendar.getTime()));
      calendar.add(Calendar.SECOND, 3);

      //1. 创建一个timer实例
      Timer timer = new Timer();
      //2. 创建一个MyTimerTask实例
      MyTimerTask myTimerTask = new MyTimerTask("No.1");

      //3. 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task,如:现在2020-10-26 14:30:00,则在2020-10-26 14:30:01执行一次task,打印任务的名字,之后每隔两秒执行一次
      myTimerTask.setName("scheduleAtFixedRate2");
      timer.scheduleAtFixedRate(myTimerTask, 1000, 2000);
      }
      }

      其他重要函数

  • TimerTask两个重要函数

    • cancel()

      • 作用:取消当前TimerTask里的任务

      • 代码示例

        改造MyTimerTask的代码

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        package com.example.timer;

        import lombok.Data;

        import java.text.SimpleDateFormat;
        import java.util.Calendar;
        import java.util.TimerTask;

        /**
        * @author jinglv
        * @date 2020/10/25
        */
        @Data
        public class MyTimerTask extends TimerTask {

        private String name;
        private Integer count = 0;

        public MyTimerTask(String name) {
        this.name = name;
        }

        @Override
        public void run() {
        // 执行三次,超过三次取消task
        if (count < 3) {
        // 以yyyy-MM-dd HH:mm:ss的格式打印当前执行时间
        // 如2020-10-25 00:00:00
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 打印当前执行时间
        System.out.println("Current exec time is:" + simpleDateFormat.format(calendar.getTime()));
        // 打印当前name的内容
        System.out.println("Current exec name is: " + name);
        count++;
        }else {
        cancel();
        System.out.println("Task cancel!");
        }
        }
        }

        测试代码

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        package com.example.timer;

        import java.util.Timer;

        /**
        * @author jinglv
        * @date 2020/10/25
        */
        public class MyTimer {

        public static void main(String[] args) {
        // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(simpleDateFormat.format(calendar.getTime()));
        calendar.add(Calendar.SECOND, 3);

        //1. 创建一个timer实例
        Timer timer = new Timer();
        //2. 创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("No.1");

        //3. 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task, 如:在2020-10-26 14:30:00执行一次task,打印任务的名字,之后每隔两秒执行一次task
        myTimerTask.setName("schedule2");
        timer.schedule(myTimerTask, calendar.getTime(), 2000);
        }
        }

        执行结果:

        image-20201026180200377

    • scheduledExecutionTime()

      • 作用:返回此任务最近实际执行的已安排执行的时间

      • 返回值:最近发生此任务执行安排的时间,为long型

      • 代码示例

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        package com.example.timer;

        import java.util.Timer;

        /**
        * @author jinglv
        * @date 2020/10/25
        */
        public class MyTimer {

        public static void main(String[] args) {
        // 获取当前时间,并设置成距离当前时间三秒之后的时间, 如当前时间2020-10-26 14:28:30, 则设置后的时间则为2020-10-26 14:28:33
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(simpleDateFormat.format(calendar.getTime()));
        calendar.add(Calendar.SECOND, 3);

        //1. 创建一个timer实例
        Timer timer = new Timer();
        //2. 创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("No.1");

        //3. 在时间等于或超过time的时候执行且执行一次task, 如:在2020-10-26 14:30:00执行一次task,打印任务的名字
        myTimerTask.setName("schedule1");
        timer.schedule(myTimerTask, calendar.getTime());
        // 返回task最近实际执行的已安排执行的时间
        System.out.println("scheduled time:" + simpleDateFormat.format(myTimerTask.scheduledExecutionTime()));

        }
        }

        执行结果

        image-20201026181704737

  • Timer

    • cancel()

      • 作用:终止此计时器,丢弃所有当前已安排的任务

      • 代码示例

        新建CancelTest.java文件

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        package com.example.timer;

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

        /**
        * @author jinglv
        * @date 2020/10/26
        */
        public class CancelTest {
        public static void main(String[] args) throws InterruptedException {
        // 创建Timer实例
        Timer timer = new Timer();
        // 创建TimerTask实例
        MyTimerTask myTimerTask1 = new MyTimerTask("task1");
        MyTimerTask myTimerTask2 = new MyTimerTask("task2");
        // 获取当前执行时间并打印
        Date startTime = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("start time is:" + simpleDateFormat.format(startTime));
        // task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
        // task2首次执行是距离现在时间1秒后执行,之后每隔2秒执行一次
        timer.schedule(myTimerTask1, 3000, 2000);
        timer.schedule(myTimerTask2, 1000, 2000);

        // 休眠5秒
        Thread.sleep(5000);

        // 获取当前的执行时间并打印
        Date cancelTime = new Date();
        System.out.println("start time is:" + simpleDateFormat.format(cancelTime));

        // 取消所有任务
        timer.cancel();
        System.out.println("Tasks all canceled!");

        }
        }

        执行结果:

        image-20201026182714951

    • purge()

      • 作用:从此计时器的任务队列中移除所有已取消的任务

      • 返回值:从队列中移除的任务数

      • 代码示例

        在CancelTest.java的基础上改造

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        package com.example.timer;

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

        /**
        * @author jinglv
        * @date 2020/10/26
        */
        public class CancelTest {
        public static void main(String[] args) throws InterruptedException {
        // 创建Timer实例
        Timer timer = new Timer();
        // 创建TimerTask实例
        MyTimerTask myTimerTask1 = new MyTimerTask("task1");
        MyTimerTask myTimerTask2 = new MyTimerTask("task2");
        // 获取当前执行时间并打印
        Date startTime = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("start time is:" + simpleDateFormat.format(startTime));
        // task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
        // task2首次执行是距离现在时间1秒后执行,之后每隔2秒执行一次
        timer.schedule(myTimerTask1, 3000, 2000);
        timer.schedule(myTimerTask2, 1000, 2000);

        System.out.println("current canceled task number is:" + timer.purge());
        // 休眠5秒
        Thread.sleep(2000);

        // 获取当前的执行时间并打印
        Date cancelTime = new Date();
        System.out.println("start time is:" + simpleDateFormat.format(cancelTime));

        // 取消myTimerTask2任务
        myTimerTask2.cancel();
        System.out.println("Tasks all canceled!");
        System.out.println("current canceled task number is:" + timer.purge());
        }
        }

        执行结果

        image-20201026183451415

schedule与scheduleAtFixedRate的区别

Quartz