java任务调度定时器_【Java定时任务调度工具】Timer

定时任务调度

基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务。

Timer 定义

一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

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

Timer 主要构建

9bcf5dadeb6145cbde5c8c78a8af4f76.png

Timer 主要成分

9a2b09da141b164c8b777478698cc666.png

Timer 定时调度函数

schedule 的四种用法

schedule(task, time)

参数

task - 所要安排的任务

time - 执行任务的时间

作用

在时间等于或超过time的时候执行且仅执行一次task

schedule(task, time, period)

参数

task - 所要安排的任务

time - 首次执行任务的时间

period - 执行一次task的时间间隔,单位是毫秒

作用

时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task

schedule(task, delay)

参数

task - 所要安排的任务

delay - 执行任务前的延迟时间,单位是毫秒

作用

等待delay毫秒后执行且仅执行一次task

schedule(task, delay, period)

参数

task - 所要安排的任务

delay - 执行任务前的延迟时间,单位是毫秒

period - 执行一次task的时间间隔,单位是毫秒

作用

等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task

scheduleAtFixedRate 的两种用法

scheduleAtFixedRate(task, time, period)

参数

task - 所要安排的任务

time - 首次执行任务的时间

period - 执行一次task的时间间隔,单位是毫秒

作用

时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task

scheduleAtFixedRate(task, delay, period)

参数

task - 所要安排的任务

delay - 执行任务前的延迟时间,单位是毫秒

period - 执行一次task的时间间隔,单位是毫秒

作用

等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task

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() {

// 以 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()));

// 打印当前name的内容

System.out.println("Current exec name is: " + name);

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

import java.text.SimpleDateFormat;

import java.util.Calendar;

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

/**

* 获取当前时间,并设置成距离当前时间三秒后的时间

*/

Calendar calendar = Calendar.getInstance();

SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

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

calendar.add(Calendar.SECOND, 3);

// 3. 通过timer定时定频率调用myTimerTask的业务逻辑

//-------------------schedule的四种用法-------------------//

/**

* 在时间等于或超过time的时间执行且仅执行一次task

*/

myTimerTask.setName("schedule_1");

timer.schedule(myTimerTask, calendar.getTime());

/**

* 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task

*/

myTimerTask.setName("schedule_2");

timer.schedule(myTimerTask, calendar.getTime(), 2000);

/**

* 等待delay毫秒后执行且仅执行一次task

*/

myTimerTask.setName("schedule_3");

timer.schedule(myTimerTask, 1000);

/**

* 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task

*/

myTimerTask.setName("schedule_4");

timer.schedule(myTimerTask, 3000, 2000);

//--------------scheduleAtFixedRate的两种用法-------------//

/**

* 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task

*/

myTimerTask.setName("scheduleAtFixedRate_1");

timer.scheduleAtFixedRate(myTimerTask, calendar.getTime(), 2000);

/**

* 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task

*/

myTimerTask.setName("scheduleAtFixedRate_2");

timer.scheduleAtFixedRate(myTimerTask, 3000, 2000);

}

}

schedule 与 scheduleAtFixedRate 的区别

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

schedule 方法

fixed-delay;如果第一次执行时间被 delay 了,随后的执行时间按照上一次实际执行完成的时间点进行计算

scheduleAtFixedRate 方法

fixed-rate;如果第一次执行时间被 delay 了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此 TimerTask 中的执行体需要考虑同步

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

schedule 方法

下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后

scheduleAtFixedRate 方法

下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性

其他重要函数

TimerTask 的 cancel()、scheduleExecutionTime()

Timer 的 cancel()、purge()

TimerTask 的两个重要函数

cancel()

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

scheduleExecutionTime()

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

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

Timer 的其他函数

cancel()

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

purge()

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

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

Timer 函数的综合应用

模拟两个机器人的定时行为

第一个机器人会隔两秒打印最近一次计划的时间、执行内容

第二个机器人会模拟往桶里倒水,直到桶里的水满为止,然后停止工作

桶里的水满了之后,第一个机器人再跳舞两秒钟,然后停止工作

/**

* 跳舞的机器人

*/

public class DancingRobot extends TimerTask {

@Override

public void run() {

// 获取最近的一次任务执行的时间,并将其格式化

SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println("Scheduled exec time is: " + sf.format(scheduledExecutionTime()));

System.out.println("Dancing happily!");

}

}

/**

* 倒水的机器人

*/

public class WaterRobot extends TimerTask {

private Timer timer;

// 最大容量为5L

private Integer bucketCapacity = 0;

public WaterRobot(Timer inputTimer) {

timer = inputTimer;

}

@Override

public void run() {

// 灌水直接至桶满为止

if(bucketCapacity < 5){

System.out.println("Add 1L water into the bucket!");

bucketCapacity ++;

} else {

// 水满之后就停止执行

System.out.println("The number of canceled task in timer is: " + timer.purge());

cancel();

System.out.println("The waterRobot has been aborted");

System.out.println("The number of canceled task in timer is: " + timer.purge());

System.out.println("Current water is " + bucketCapacity + "L");

// 等待两秒钟,终止timer里面的所有内容

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

timer.cancel();

}

}

}

public class Executor {

public static void main(String[] args) {

Timer timer = new Timer();

// 获取当前时间

Calendar calendar = Calendar.getInstance();

SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

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

DancingRobot dr = new DancingRobot();

WaterRobot wr = new WaterRobot(timer);

timer.schedule(dr, calendar.getTime(), 2000);

timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000);

}

}

Timer 的缺陷

管理并发任务的缺陷

Timer 有且只有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符

当任务抛出异常时的缺陷

如果 TimerTask 抛出 RuntimeException,Timer 会停止所有任务的运行

Timer 的使用禁区

对时效性要求较高的多任务并发作业

对复杂的任务的调度

扩展阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值