一、Timer的定义:
有且仅有一个后台线程 对 多个业务线程 进行 定时定频率 的调度
二、timer和timerTask方法使用
任务方法对象TimerTask :cancel() 、scheduledExecutionTime() 、run()
public class MyTimerTask extends TimerTask {
private String name;
private static Integer count = 0;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
if (count < 3) {
System.out.println(name + "我来执行啦!!!!");
count++;
} else {
cancel();//运行3次后,关闭任务,但是调度的timer.schedule方法还在运行
System.out.println("3次后强制结束任务");
}
}
}
任务调度对象 Timer:cancel() 、purge() 、schedule、scheduleAtFixedRate
public class MyTimer {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
MyTimerTask timerTask = new MyTimerTask("xiao");
//日期对象
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sf.format(System.currentTimeMillis()) + "=====" + sf.format(calendar.getTime()));
calendar.add(Calendar.SECOND, 10); //增加10秒
System.out.println(sf.format(calendar.getTime()));
/*
// 单位毫秒,2秒后只执行一次任务
timer.schedule(timerTask, 2000);
// 到达执行时间或超过之后,间隔一秒执行一次
timer.schedule(timerTask,calendar.getTime(),1000);
*/
//当前时间延时2秒在运行任务,间隔1秒发送一次
timer.schedule(timerTask, 2000, 1000);
System.out.println("最近一次安排任务的时间是" + sf.format(timerTask.scheduledExecutionTime()));
Thread.sleep(10000l);//休眠10秒,调度任务还在执行中
timer.cancel();//取消所有任务
System.out.println("已取消的任务有几个,并从当前队列中移除" + timer.purge());
}
}
运行结果:
2019-09-01 18:49:16=====2019-09-01 18:49:16
2019-09-01 18:49:26
最近一次安排任务的时间是2019-09-01 18:49:17
xiao我来执行啦!!!!
xiao我来执行啦!!!!
xiao我来执行啦!!!!
3次后强制结束任务
已取消的任务有几个0
Process finished with exit code 0
三、出现问题
1、首次计划执行时间早于当前时间
2、任务执行所需时间超过间隔时间
public class NewTimer {
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()));
calendar.add(Calendar.SECOND, -10);
System.out.println("任务应该执行的时间是" + sf.format(calendar.getTime()));
/* //如果执行时间晚于任务规定时间,还是按2秒间隔执行
timer.schedule(new TimerTask() { */
//如果执行时间晚于任务规定时间,会在当前时间之前执行,追赶完成之前的任务,按2秒间隔执行
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("当前已安排的任务执行的时间是" + sf.format(scheduledExecutionTime()));
System.out.println("当前任务执行完!!!!!!!" );
}
}, calendar.getTime(), 2000);
}
}
结果:
当前的时间是2019-09-01 19:33:34
任务应该执行的时间是2019-09-01 19:33:24
当前任务执行的时间是2019-09-01 19:33:24
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:26
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:28
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:30
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:32
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:34
当前任务执行完!!!!!!!
当前任务执行的时间是2019-09-01 19:33:36
当前任务执行完!!!!!!!
。。。。
总结
1.管理并发任务的缺陷:
每次有且仅有一个后台线程去执行定时任务,如存在多任务会导致任务时间过长(串行)
2.当任务抛出异常时的缺陷:
当抛出RuntimeException(如果不捕捉异常),会停止后面的所有任务
3.在以下情况禁止使用
对时效性要求较高的多任务并发作业
4.周期性又有周期性的不适合(每周三执行一次,也不行,需要使用quartz)