Java定時任務調度工具Timer

前言:

首先咱們先明確一下什麼是定時任務調度?java

基於給定的時間點,給定的時間間隔或者給定的執行次數自動執行的任務。api

Java中定時任務調動工具備倆:Timer 、Quartz多線程

區別:併發

    出身不一樣:Timer由jdk直接提供,不需jar包支持;Quartz需引入jar包。ide

    能力不一樣:Timer簡單定時任務;Quartz時間控制功能更強大。函數

    底層機制:Timer只有一個後臺線程執行;Quartz是多線程執行任務。工具

一.Timer簡介:

    讓咱們看下官方文檔api(JDK1.8)this

可能有的小夥伴英語水平不太好,那讓咱們看下中文版吧:spa

 

那麼咱們能夠概括Timer的定義:有且僅有一個後臺線程對多個業務線程進行定時定頻率的調度線程

主要構件:

 

Timer工具類詳解:

二.Timer實戰

1.簡單實戰

1)定時任務類

package com.leo.timer;

import java.util.TimerTask;

public class MyTimerTask extends TimerTask {
    private String name;

    public MyTimerTask(String inputName){
        name=inputName;
    }


    @Override
    public void run() {
        //打印當前name的內容
        System.out.println("Current exec name is"+name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2)Timer啓動

package com.leo.timer;

import java.util.Timer;

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);
    }
}

控制檯打印顯示:

 

2.Timer的定時調度函數

1)schedule的四種用法

    1.schedule(task,time)

        做用:在時間等於或超過time的時候執行且僅執行一次task

    2.schedule(task,time,period)

        參數:    task-所要安排的任務

                      time-首次執行任務的時間

                      period-執行一次task的時間間隔,單位是毫秒

    3.schedule(task,delay)

        參數:    task-所要安排的任務

                      delay-執行任務前的延遲時間,單位是毫秒

        做用:    等待delay毫秒後執行且僅執行一次task

    4.schedule(task,delay,period)

        參數:    task-所要安排的任務

                      delay-執行任務前的延遲時間,單位是毫秒

                      period-執行一次task的時間間隔,單位是毫秒

        做用:    等待delay毫秒後執行且僅執行一次task,以後每隔period毫秒重複執行一次task

具體代碼以下:

    定時任務類:

    

package com.leo.timer;

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

public class MyTimerTask extends TimerTask {
    private String name;

    public MyTimerTask(String inputName){
        name=inputName;
    }


    @Override
    public void run() {
        //打印當前name的內容
        System.out.println("Current exec name is "+name);
        //以yyyy-MM-dd HH:mm:ss的格式打印當前執行時間
        Calendar calendar=Calendar.getInstance();
        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current exec time is"+sf.format(calendar.getTime()));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

    四中啓動類:

        

package com.leo.timer;

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

public class MyTimer {
    public  static void  main(String[] args){
        //一.建立一個timer實例
        Timer timer=new Timer();
        //二.建立一個MyTimerTask實例
        MyTimerTask myTimerTask=new MyTimerTask("No.1");
        //三.經過timer定時頻率調用myTImerTask的業務邏輯
        // 既第一次執行是在當前時間的兩秒以後,以後每隔一秒鐘執行一次
        //timer.schedule(myTimerTask,2000L,1000L);

        /**
         * 獲取當前時間,並設置成距離當前時間三秒以後的時間
         * 若是當前時間是2017-10-21 23:59:57
         * 則設置後的時間則爲2017-10-22 00:00:00
         */
        Calendar calendar=Calendar.getInstance();
        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sf.format(calendar.getTime()));
        calendar.add(Calendar.SECOND,3);
        /**
         * 1.  schedule(task,time)
         *      在時間等於或超過time的時候執行且僅執行一次task
         *      如在2017-10-22 00:00:00 執行一次task:打印任務的名字
         */
        //myTimerTask.setName("schedule1");
        //timer.schedule(myTimerTask,calendar.getTime());
        /**
         * 2. schedule(task,time,period)
         *      時間等於或超過time時首次執行task
         *      以後每隔period毫秒重複執行一次task
         *      如在2017-10-22 00:00:00 第一次執行task:打印任務的名字
         *      以後每隔兩秒執行一次task
         */
        //myTimerTask.setName("schedule2");
        //timer.schedule(myTimerTask,calendar.getTime(),2000);
        /**
         * 3. schedule(task,delay)
         *      等待delay毫秒後執行且僅執行一次task
         *      如如今是2017-10-22 00:00:00
         *      則在2017-10-22 00:00:01執行一次task::打印任務的名字
         */
        //myTimerTask.setName("schedule3");
        //timer.schedule(myTimerTask,1000);
        /**
         * 4.  schedule(task,delay,period)
         *      等待delay毫秒後首次執行task
         *      如如今是2017-10-22 00:00:00
         *      則在2017-10-22 00:00:01執行一次task::打印任務的名字
         *      以後每隔兩秒執行一次task
         */
         myTimerTask.setName("schedule4");
         timer.schedule(myTimerTask,calendar.getTime(),2000);
    }
}

2)scheduleAtFixedRate的四種用法           

    1.scheduleAtFixedRate(task,time,period)

        參數:    task-所要安排的任務

                      time-首次執行任務的時間

                      period-執行一次task的時間間隔,單位是毫秒    

       做用:    時間等於或超過time時首次執行task,以後每隔period毫秒重複執行一次task(和schedule的第二種用法是同樣的)

    2.scheduleAtFixedRate(task,delay,period)

        參數:    task-所要安排的任務

                      delay-執行任務前的延遲時間,單位是毫秒

                      period-執行一次task的時間間隔,單位是毫秒

        做用:    等待delay毫秒後執行且僅執行一次task,以後每隔period毫秒重複執行一次task(和schedule的第四種用法是同樣的)

代碼:

//----------------scheduleAtFixedRate的用法-------------------------------
        /**
         * 1 . scheduleAtFixedRate(task,time,period)
         *      時間等於或超過time時首次執行task
         *      以後每隔period毫秒重複執行一次task
         *      如在2017-10-22 00:00:00 第一次執行task:打印任務的名字
         *      以後每隔兩秒執行一次task
         */
        //myTimerTask.setName("scheduleAtFixedRate1");
        //timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
        /**
         * 2.  scheduleAtFixedRate(task,delay,period)
         *      等待delay毫秒後首次執行task
         *      如如今是2017-10-22 00:00:00
         *      則在2017-10-22 00:00:01執行一次task::打印任務的名字
         *      以後每隔兩秒執行一次task
         */
        myTimerTask.setName("scheduleAtFixedRate2");
        timer.scheduleAtFixedRate(myTimerTask,3000,2000);

 

咱們先來看Timer的其餘重要函數,下一標題再具體講解schedule和schedulAtFixedRate兩者的不一樣

3)其餘重要函數

    1.TimerTask的cancel(),scheduledExecutionTime() :

        cancel:

            做用:取消當前TimerTask裏的任務

        

@Override
    public void run() {
        if (count<3){
            //打印當前name的內容
            System.out.println("Current exec name is "+name);
            //以yyyy-MM-dd HH:mm:ss的格式打印當前執行時間
            Calendar calendar=Calendar.getInstance();
            SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("Current exec time is"+sf.format(calendar.getTime()));
            count++;
        }else {
            cancel();
            System.out.println("Task cancel");
        }
    }

        scheduledExecutionTime():

            做用:返回此任務最近實際執行的已安排執行的時間

 

    2.Timer的cancel() , perge() :

        cancel():

            做用:終止此計時器,丟棄全部當前已安排的任務

        

        purge():

            做用:今後計時器的任務隊列中移除所要已取消的任務

            返回值:從隊列中移除的任務數

3.schedule和scheduleAtFixeRate的區別

1)首次計劃執行的時間早於當前的時間

    1.schedule方法:

            "fixed-delay"若是第一次執行時間被delay了,隨後的執行時間按上一次實際執行完成的時間點進行計算

console:

    2.scheduleAtFixedRate方法:

            "fixed-rate"若是第一次執行時間被delay了,隨後的執行時間按上一次實際執行完成的時間點進行計算,而且爲了遇上進度會屢次執行任務,所以TimerTask中的執行體須要考慮同步

console:

 

 2)任務執行所需時間超出任務的執行週期間隔

    1.schedule方法:

            下一次執行時間相對於上一次實際執行完成的時間點,所以執行時間會不斷延後

console:

    2.scheduleAtFixedRate方法:

            下一次執行時間相對於上一次開始的時間點,所以執行的時間不會延後,所以存在併發性

console:

4.Timer的缺陷:

1)管理併發任務的缺陷

    Timer有且僅有一個線程去執行定時任務,若是存在多個定時任務,且任務時間過長,會致使執行效果與預期不符

console:

一樣scheduleAtFixedRate也不能解決併發問題:

2)當任務拋出異常時的缺陷

    若是TimerTask拋出RuntimeException,Timer會中止全部任務的執行

三.Timer的使用禁區:

1.對時效性要求較高的多任務併發做業

2.對複雜的任務的調度

若是想要知足以上功能,需用到Quartz

相關文章
相關標籤/搜索