定时任务调度工具之Timer(三)

定时任务调度工具之Timer(三)

一、Timer中的其他函数

1.TimerTask类的cancel()

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

MyTimerTask:

package com.hcx.timer;

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

/**
 * Created by HCX on 2017/8/28.
 * 需要定时调度的业务逻辑类
 */
public class MyTimerTask extends TimerTask{

    private String name;
    private Integer count = 0;

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

    @Override
    public void run() {
        /*
        不希望任务一直不断的重复执行,需求:只执行三次
         */
        if(count<3){
            /*
         * 以yyyy-MM-dd HH:mm:ss的格式打印当前执行时间
         * 如:2017-8-29 00:00:00
         */
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("Current exec time is(task) : " + sf.format(calendar.getTime()));
            // 打印当前 name 的内容
            System.out.println("Current exec name is(task) : " + name);
            count++;
        }else {
            cancel();
            System.out.println("任务取消了");
        }
    }

    public String getName() {
        return name;
    }

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

MyTimer:

package com.hcx.timer;

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

/**
 * Created by HCX on 2017/8/28.
 * 定时调度类
 */
public class MyTimer {

    public static void main(String[] args){

        //创建一个Timer实例(位于java.util包下的)
        Timer timer = new Timer();
        //创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("hcx");
        /*
         * 通过Timer定时定频率调用MyTimerTask的业务逻辑
         * 即第一次执行是在当前时间的两秒钟之后,之后每隔一秒钟执行一次
         */
        //timer.schedule(myTimerTask,2000L,1000L);
        /**
         * 获取当前时间,并设置成距离当前时间三秒之后的时间
         * 如当前时间是2017-08-29 23:59:57
         * 则设置后的时间则为2017-8-30 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()));
        //设置距离当前时间3秒之后的时间
        //calendar.add(Calendar.SECOND,3);
        /**
         * 等待delay毫秒后首次执行task
         * 之后每隔period毫秒重复执行一次task
         * 如现在是2017-08-30 00:00:00
         * 则现在2017-08-30 00:00:03执行一次task:打印任务的名字
         * 并且之后每隔两秒会一直不断重复执行下去
         */
         myTimerTask.setName("schedule");
         timer.schedule(myTimerTask,3000,2000);
         /*
         执行结果:
            Current exec time is : 2017-08-30 10:09:44
            Current exec time is(task) : 2017-08-30 10:09:47
            Current exec name is(task) : schedule
            Current exec time is(task) : 2017-08-30 10:09:49
            Current exec name is(task) : schedule
            Current exec time is(task) : 2017-08-30 10:09:51
            Current exec name is(task) : schedule
            任务取消了
          */
    }
}

2.TimerTask类的scheduleExecutionTime()

作用: 返回此任务最近实际执行的已安排执行的时间
比如计划的时间是让任务3秒钟之后执行,返回的时间就是距离当前时间3秒钟之后的时间
返回值:最近发生此任务执行安排的时间,为long型

MyTimer:

package com.hcx.timer;

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

/**
 * Created by HCX on 2017/8/28.
 * 定时调度类
 */
public class MyTimer {

    public static void main(String[] args){

        //创建一个Timer实例(位于java.util包下的)
        Timer timer = new Timer();
        //创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("hcx");
        /*
         * 通过Timer定时定频率调用MyTimerTask的业务逻辑
         * 即第一次执行是在当前时间的两秒钟之后,之后每隔一秒钟执行一次
         */
        //timer.schedule(myTimerTask,2000L,1000L);
        /**
         * 获取当前时间,并设置成距离当前时间三秒之后的时间
         * 如当前时间是2017-08-29 23:59:57
         * 则设置后的时间则为2017-8-30 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()));
        //设置距离当前时间3秒之后的时间
        //calendar.add(Calendar.SECOND,3);
        /**
         * 等待delay毫秒后首次执行task
         * 之后每隔period毫秒重复执行一次task
         * 如现在是2017-08-30 00:00:00
         * 则现在2017-08-30 00:00:03执行一次task:打印任务的名字
         * 并且之后每隔两秒会一直不断重复执行下去
         */
        myTimerTask.setName("schedule");
        timer.schedule(myTimerTask,3000); //只执行一次
        System.out.println("schedule time is " + simpleDateFormat.format(myTimerTask.scheduledExecutionTime()));
        /*
        执行结果:
        Current exec time is : 2017-08-30 10:30:54
sche    schedule time is 2017-08-30 10:30:57
         */

    }
}

3.Timer的cancel()

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

CancelTest:

package com.hcx.timer;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class CancelTest {

    public static void main(String[] args) throws InterruptedException {
        // 创建Timer实例
        Timer timer = new Timer();
        // 创建TimerTask实例
        MyTimerTask task1 = new MyTimerTask("task1");
        MyTimerTask task2 = 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(task1,3000,2000);
        timer.schedule(task2,1000,2000);
        // 休眠5秒
        Thread.sleep(5000);
        // 获取当前的执行时间并打印
        Date cancelTime = new Date();
        System.out.println("cancel time is : " + simpleDateFormat.format(cancelTime));

        // 取消所有任务
        timer.cancel();
        System.out.println("Tasks all canceled!");
        /**
         * 执行结果:
         * start time is : 2017-08-30 10:52:54
           Current exec time is(task) : 2017-08-30 10:52:55
           Current exec name is(task) : task2
           Current exec time is(task) : 2017-08-30 10:52:57
           Current exec name is(task) : task1
           Current exec time is(task) : 2017-08-30 10:52:57
           Current exec name is(task) : task2
           cancel time is : 2017-08-30 10:52:59
           Tasks all canceled!
         */

    }
}

4.Timer的purge()

作用:从此计时器的任务队列中移除所有已取消的任务
例:有两个task在同一个timer下去执行,其中的一个task因为某种原因,被取消了;此时调用purge(),就会将已取消的task从队列中移除,并且会返回一个
返回值:从队列中移除的任务数

CancelTest:

package com.hcx.timer;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class CancelTest {

    public static void main(String[] args) throws InterruptedException {
        // 创建Timer实例
        Timer timer = new Timer();
        // 创建TimerTask实例
        MyTimerTask task1 = new MyTimerTask("task1");
        MyTimerTask task2 = 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(task1,3000,2000);
        timer.schedule(task2,1000,2000);
        System.out.println("当前已取消的任务数为 : " + timer.purge());
        // 休眠2秒
        Thread.sleep(2000);
        // 获取当前的执行时间并打印
        Date cancelTime = new Date();
        System.out.println("cancel time is : " + simpleDateFormat.format(cancelTime));

        // 取消task2
        task2.cancel();
        System.out.println("当前已取消的任务数为 : " + timer.purge());

    }
}

运行结果:

start time is : 2017-08-30 11:13:11
当前已取消的任务数为 : 0
Current exec time is(task) : 2017-08-30 11:13:12
Current exec name is(task) : task2
cancel time is : 2017-08-30 11:13:13
当前已取消的任务数为 : 1
Current exec time is(task) : 2017-08-30 11:13:14
Current exec name is(task) : task1
二、schedule和scheduleAtFixedRate的区别

1.首次计划执行的时间早于当前的时间

例如当前的时间为2017-08-30 00:00:05,计划上的第一次执行时间为2017-08-30 00:00:00,时间早于当前的执行时间。

1.schedule方法
“fixed-delay”,如果第一次执行时间被delay了,
随后的执行时间按照上一次实际执行完成的时间点进行计算
2.scheduleAtFixedRate方法
“fixed-rate”,如果第一次执行时间被delay了(第一次执行的时间早于现在的时间),
随后的执行时间按照上一次开始的时间点进行计算,
并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步

代码演示schedule方法:

package com.hcx.timer2;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class DifferenceTest {

    public static void main(String[] args){
        // 定义时间格式
        final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前的具体时间
        Calendar calendar = Calendar.getInstance();

        System.out.println("Current time is : " + sf.format(calendar.getTime()));
        // 设置成6秒前的时间,若当前时间为2017-08-30 00:00:06·
        // 那么设置之后时间变成2017-08-30 00:00:00
        calendar.add(Calendar.SECOND,-6);

        Timer timer = new Timer();

        // 第一次执行时间为6秒前,之后每隔两秒钟执行一次
        //使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
        timer.schedule(new TimerTask() {


            public void run() {
                // 打印当前的计划执行时间
                System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
                //scheduledExecutionTime():获取TimerTask最近的一次计划执行时间  sf.format(scheduledExecutionTime()));
                System.out.println("任务正在执行");
            }
        }, calendar.getTime(), 2000);

    }

}

执行结果:

Current time is : 2017-09-04 11:41:03
Schedule exec time is : 2017-09-04 11:41:03
任务正在执行
Schedule exec time is : 2017-09-04 11:41:05
任务正在执行
Schedule exec time is : 2017-09-04 11:41:07
任务正在执行
Schedule exec time is : 2017-09-04 11:41:09
任务正在执行
...

scheduleAtFixedRate方法:

package com.hcx.timer2;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class DifferenceTest {

    public static void main(String[] args){
        // 定义时间格式
        final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前的具体时间
        Calendar calendar = Calendar.getInstance();

        System.out.println("Current time is : " + sf.format(calendar.getTime()));
        // 设置成6秒前的时间,若当前时间为2017-08-30 00:00:06·
        // 那么设置之后时间变成2017-08-30 00:00:00
        calendar.add(Calendar.SECOND,-6);

        Timer timer = new Timer();

        // 第一次执行时间为6秒前,之后每隔两秒钟执行一次
        //使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                // 打印当前的计划执行时间
                System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
                //scheduledExecutionTime():获取TimerTask最近的一次计划执行时间  sf.format(scheduledExecutionTime()));
                System.out.println("任务正在执行");
            }
        }, calendar.getTime(), 2000);

    }

}

执行结果:

Current time is : 2017-09-04 11:50:36
Schedule exec time is : 2017-09-04 11:50:30
任务正在执行
Schedule exec time is : 2017-09-04 11:50:32
任务正在执行
Schedule exec time is : 2017-09-04 11:50:34
任务正在执行
Schedule exec time is : 2017-09-04 11:50:36
任务正在执行
Schedule exec time is : 2017-09-04 11:50:38
任务正在执行
Schedule exec time is : 2017-09-04 11:50:40
任务正在执行
Schedule exec time is : 2017-09-04 11:50:42
任务正在执行
...

2.任务执行所需时间超出任务的执行周期间隔

例如任务需要每隔2秒都执行一次,但是单次完成任务的时间需要3秒,此时就超出了任务执行的周期间隔。

1. schedule方法
下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
2.scheduleAtFixedRate方法
下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性

代码演示schedule方法:

package com.hcx.timer2;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class DifferenceTest {

    public static void main(String[] args){
        // 定义时间格式
        final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前的具体时间
        Calendar calendar = Calendar.getInstance();

        System.out.println("Current time is : " + sf.format(calendar.getTime()));

        Timer timer = new Timer();

        // 第一次执行时间为6秒前,之后每隔两秒钟执行一次
        //使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
        timer.schedule(new TimerTask() {

            public void run() {
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                // 打印当前的计划执行时间
                System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
                //scheduledExecutionTime():获取TimerTask最近的一次计划执行时间  sf.format(scheduledExecutionTime()));
                System.out.println("任务正在执行");
            }
        }, calendar.getTime(), 2000);

    }

}

运行结果:

Current time is : 2017-09-04 14:30:51
Schedule exec time is : 2017-09-04 14:30:51
任务正在执行
Schedule exec time is : 2017-09-04 14:30:54
任务正在执行
Schedule exec time is : 2017-09-04 14:30:57
任务正在执行
Schedule exec time is : 2017-09-04 14:31:00
任务正在执行
Schedule exec time is : 2017-09-04 14:31:03
任务正在执行
...

代码演示scheduleAtFixedRate方法:

package com.hcx.timer2;

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

/**
 * Created by HCX on 2017/8/30.
 */
public class DifferenceTest {

    public static void main(String[] args){
        // 定义时间格式
        final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前的具体时间
        Calendar calendar = Calendar.getInstance();

        System.out.println("Current time is : " + sf.format(calendar.getTime()));

        Timer timer = new Timer();

        // 第一次执行时间为6秒前,之后每隔两秒钟执行一次
        //使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                // 打印当前的计划执行时间
                System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
                //scheduledExecutionTime():获取TimerTask最近的一次计划执行时间  sf.format(scheduledExecutionTime()));
                System.out.println("任务正在执行");
            }
        }, calendar.getTime(), 2000);

    }

}

执行结果:

Current time is : 2017-09-04 14:34:21
Schedule exec time is : 2017-09-04 14:34:21
任务正在执行
Schedule exec time is : 2017-09-04 14:34:23
任务正在执行
Schedule exec time is : 2017-09-04 14:34:25
任务正在执行
Schedule exec time is : 2017-09-04 14:34:27
任务正在执行
...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值