一.定义
- 有且仅有一个后台线程对多个业务线程进行定时定频率的调度.
二.简单使用
首先创建TimerTask类,实现业务逻辑的run方法.
private String name;
public MyTimerTask(String inputname) {
this.name = inputname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void run() {
System.out.println("Current name is:" + name);
}
通过timer调用task来定时定频率的执行
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过timer定时定频率调用myTimerTask的业务逻辑
//第一次执行实在当前时间的两秒后,每隔1秒执行一次.
timer.schedule(myTimerTask, 2000L, 1000L);
三.schedule的四种用法
1.schedule的前两种用法
a.规定时间后执行一次
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过timer定时定频率调用myTimerTask的业务逻辑
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);
myTimerTask.setName("schedule1");
//三秒后执行一次
timer.schedule(myTimerTask, calendar.getTime());
b.时间等于或超过time首次执行task,之后每隔period毫秒重复执行一次task
//三秒后执行一次,之后每隔2秒重复执行一次task
timer.schedule(myTimerTask, calendar.getTime(), 2000L);
2.schedule的后两种方法
a.参数不是time而是delay
//三秒后执行一次
timer.schedule(myTimerTask, 3000L);
b.参数不是time而是delay
//三秒后执行一次,之后每隔2秒重复执行一次task
timer.schedule(myTimerTask, 3000L,2000L);
四.scheduleAtFixedRate的两种用法
1.time参数
三个参数
- task - 所安排的任务
- time - 首次执行任务的时间
- period - 重复的时间间隔
timer.scheduleAtFixedRate(task,time,period);
2.delay参数
- task - 所安排的任务
- delay- 首次执行任务的时间,距离当前时间多少毫秒
- period - 重复的时间间隔
timer.scheduleAtFixedRate(task,delay,period);
五.其他函数
1.TimerTask的cancel(),scheduledExecutionTime()
- cancel()
作用:取消当前TimerTask里的任务
思路是在TimerTask列中,创建一个属性,记录重复次数,然后在run()方法中判断这个次数,当想让停止的时候调用cancel()方法.就会取消定时任务.
- scheduledExecutionTime()
作用:返回此任务最近实际执行的已安排执行的时间.为long型.
2.Timer的cancel(),purge()
- cancel()
作用:终止此计时器,丢弃所有当前已安排的任务.也就是这个Timer下的所有Task都会被取消掉. - purge()
作用:从此计时器的任务队列中移除所有已取消的任务;返回值是移除的任务数.
六.schedule和scheduleAtFixedRate的区别
两种情况看区别
- 首次计划执行的时间早于当前的时间
1.schedule方法:如果第一次执行时间被delay了,随后执行的时间按照上一次实际执行完成的时间点进行计算.也就是说如果schedule的第一次执行时间早于现在的时间,那么程序会马上执行一次,然后按传入的时间间隔重复执行.
2.scheduleAtFixedRate方法:如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体要考虑同步.也就是说如果scheduleAtFixedRate的第一次执行时间早于现在时间,那么程序会先把之前那段时间的task任务执行一遍,再来执行当前时间的任务,然后按照传入的时间间隔重复执行. - 任务执行所需时间超出任务的执行周期间隔
1.schedule方法:下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后.
2.scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性.
七.综合应用
跳舞机器人和灌水机器人的例子
- 跳舞机器人代码
public class DancingRobot extends TimerTask {
public void run() {
//获取最近的一次任务执行的时间并将其格式化
SimpleDateFormat sf = new SimpleDateFormat("yyy-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 {
//最大容量为5
private Integer bucketCapacity = 0;
private Timer timer;
public WaterRobot(Timer inputTimer) {
this.timer = inputTimer;
}
public void run() {
//灌水,直到桶满为止
if (bucketCapacity < 5) {
System.out.println("Add 1 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);
//等待两秒钟,终止timer里面的所有内容
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timer.cancel();
System.out.println("The number of canceled task in timer is:" + timer.purge());
}
}
}
- 执行类
public class Executor {
public static void main(String[] args) {
Timer timer = new Timer();
//获取当前的时间
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyy-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的缺陷
1. 管理并发任务的缺陷
- Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符.
2. 任务抛出异常时的缺陷
- 如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行.
九.Timer的使用禁区
- 对时效性要求较高的多任务并发作业.
- 对复杂任务的调度.
- 这时候需要大哥
网友评论