定时任务调度工具之Timer(四)
一、Timer函数的综合应用
需求:实现两个机器人
第一个机器人会隔两秒打印最近一次计划的时间、执行内容
第二个机器人会模拟往桶里倒水,直到桶里的水满为止
灌水机器人执行流程:
跳舞机器人执行流程:
代码演示:
1.创建跳舞机器人
package com.hcx.timer4;
import java.text.SimpleDateFormat;
import java.util.TimerTask;
/**
* Created by HCX on 2017/9/4.
* 跳舞机器人
*/
public class DancingRobot extends TimerTask{
@Override
public void run() {
//获取最近的一次任务执行时间,并将其格式化
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("最近的一次任务执行时间是:"+sf.format(scheduledExecutionTime()));
System.out.println("跳舞机器人在跳舞");
}
}
2.创建灌水机器人
package com.hcx.timer4;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by HCX on 2017/9/5.
* 灌水机器人
*/
public class WaterRobot extends TimerTask{
//桶的最大容量为5L
private Integer bucketCapacity = 0;
private Timer timer;
public WaterRobot(Timer timer) {
this.timer = timer;
}
@Override
public void run() {
//灌水直至桶满为止
if(bucketCapacity<5){
System.out.println("灌水机器人加一升水到桶中");
bucketCapacity++;
}else {
//取消之前打印一次
System.out.println("timer下被取消的任务数量是:" + timer.purge());
//水满之后就停止执行
//timerTask的cancel:只是取消单个实例,即取消单个TimerTask实例的任务执行
cancel();
System.out.println("灌水机器人已经停止执行了");
//timer.purge():返回timer下面的已被取消的任务数,本身的作用是移除已被取消的timertask实例的内存
//取消之后打印一次
System.out.println("timer下被取消的任务数量是:" + timer.purge());
//打印当前的水容量
System.out.println("当前的水容量是:" + bucketCapacity + "L");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Timer的cancel,取消timer实例下面的所有计划的task的执行
timer.cancel();
}
}
}
3.创建执行类
package com.hcx.timer4;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
/**
* Created by HCX on 2017/9/5.
* 执行类
*/
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("当前时间为:" + 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);
/**
* 实现当WaterRobot灌满水之后,继续让DancingRobot跳舞2秒钟再停止执行
*/
}
}
运行结果:
当前时间为:2017-09-05 16:01:37
最近的一次任务执行时间是:2017-09-05 16:01:37
跳舞机器人在跳舞
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
最近的一次任务执行时间是:2017-09-05 16:01:39
跳舞机器人在跳舞
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
最近的一次任务执行时间是:2017-09-05 16:01:41
跳舞机器人在跳舞
timer下被取消的任务数量是:0
灌水机器人已经停止执行了
timer下被取消的任务数量是:1
当前的水容量是:5L
Process finished with exit code 0
二、Timer的缺陷
1.管理并发任务的缺陷
Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符
2.当任务抛出异常时的缺陷
如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行
Timer的使用禁区:
(1)对时效性要求较高的多任务并发作业
(2)对复杂任务的调度