本篇内容:
什么是定时任务调度?
Java定时任务调度工具详解之 Timer篇
Java定时任务调度工具详解之 Quartz篇
定时任务调度:基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行任务。
Java中定时调度工具:Timer 和 Quartz的区别
1.来源:
Timer由JDK自带,不需要引入多余的jar支持。Quartz需要引入jar包。
2.能力:Quartz时间控制更强大,完善。
3.Timer只有一个后台线程执行任务,Quartz拥有后台执行线程池能够使用多个线程执行任务.
能用 Timer 处理的时候,尽量用 Timer 处理。因为 Quartz 需要的资源更多(写法也不一样)。
ps:Quartz功能比Timer更牛逼,能用Timer就别让Quartz登场, 因为出场费很贵的。
Java定时任务调度工具详解之Timer篇
Timer的定义:有且仅有一个后台线程对多个业务线程进行定时定频率的调度
Timer主要构件:Timer定时器 TimerTask定时任务
通过 timer.schedule(myTimerTask, 2000L, 1000L) ,来定时调度
Timer的定时调度函数
Schedule 和 ScheduleAtFixedRate 区别:
Schedule,ScheduleAtFixedRate具有同步并发性。
1.schedule不具有并发性。下一次执行时间是相对于上一次任务结束的时间点。因此存在时间延后,不存在并发性。
2.scheduleAtFixedRate同步并发性。下一次执行时间是相对于上一次执行任务的开始时间点。为了赶上进度。因此执行时间一般不会延误,因此存在并发性。
timer的schedule和scheduleAtFixedRate方法一般情况下是没什么区别的,只在某个情
况出现时会有区别--当前任务没有来得及完成下次任务又交到手上。
定时任务的执行周期是2s一次,但任务执行需要3s。
此时,schedule 会在第一次任务执行之后,也就是3s之后执行任务。
但是,scheduleAtFixedRate会在第一次执行的2s之后,第二次执行定时任务。
我们来举个例子:
暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业。
老师要求学生暑假每天写2页,30天后完成作业。
这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业。任务被拖延了。
这时候两个学生采取的策略就不同了:
schedule重新安排了任务时间,旅游回来的第一天做第11天的任务,第二天做第12天的任务,最后完成任务花了35天。
scheduleAtFixedRate是个守时的学生,她总想按时完成老师的任务,于是在旅游回来的第一天把之前5天欠下的任务以及第16天当天的任务全部完成了,之后还是按照老师的原安排完成作业,最后完成任务花了30天。
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;
public class Test01 {
public static void main(String[] args) {
final Timer timer = new Timer();
//timer.scheduleAtFixedRate(new TimerTask() {
timer.schedule(new TimerTask() {//分别注释这行和上面这行试一试效果
int count = 1;
@Override
public void run() {
count++;
if (count == 10) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("延迟5s");
e.printStackTrace();
}
}
SimpleDateFormat sf = new SimpleDateFormat(
"yyyy MM dd hh:mm:ss");
System.out.println("当前时间:"
+ sf.format(System.currentTimeMillis()) + "计划时间:"
+ sf.format(scheduledExecutionTime()));
}
}, 1000, 1000);
}
}
Timer的缺陷:
1.管理并发任务的缺陷:每次有且仅有一个线程去执行定时任务,如存在多任务会导致任务时间过长(串行)
2.当任务抛出异常时的缺陷:当抛出RuntimeException(如果不捕捉异常),会停止所有任务
3.在以下情况禁止使用
对时效性要求较高的多任务并发作业/对复杂的任务的调度
Java定时任务调度工具详解之 Quartz篇
Quartz特点:
1.强大的调度功能
2.灵活的应用方式
3.分布式和集群能力
三个核心:Jobdetail(调度器),Trigger(触发器) ,Scheduler (任务),就能轻松使用Quartz;
JobDetail用来绑定Job,并且在Job执行的时候携带一些执行的信息;
JobDetail和Tigger通过Builder模式创建;
Scheduler通过Factory模式创建;
public static void main(String[] args) throws SchedulerException, InterruptedException {
// 打印当前的时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Time Is : " + sf.format(date));
// 创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob").build();
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity("myTrigger", "group1")
.withSchedule(
CronScheduleBuilder.cronSchedule("* * * * * ?"))
.build();
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
System.out.println("scheduled time is :"
+ sf.format(scheduler.scheduleJob(jobDetail, trigger)));
//scheduler执行两秒后挂起
Thread.sleep(2000L);
//shutdown(true)表示等待所有正在执行的job执行完毕之后,再关闭scheduler
//shutdown(false)即shutdown()表示直接关闭scheduler
scheduler.shutdown(false);
System.out.println("scheduler is shut down? " + scheduler.isShutdown());
}
一.浅谈Job&JobDetail
JobDetail为Job提供的重要属性
可以通过 jobDetail 的 getKey() 方法来获取相关信息
jobDetail.getKey().getName(); // 获取名称
jobDetail.getKey().getGroup(); // 获取组名称
jobDetail.getJobClass.getName() // 获取Job class 的名称
jobDataMap //用来存储特定Job实例的状态信息。
二.JobExecutionContext & JobDataMap
JobExecutionContext
概念:Job能通过JobExecutionContext访问Quartz运行环境以及Job的明细数据,当Scheduler调用Job时能将数据传递给execute()方法
JobDataMap
概念:是一个JDK中Map接口实例,在任务调度时存在于JobExecutionContext中,可将参数对象传递给在运行的Job实例;而且,它自身有方便的方法可存取基本数据类型
获取方式:从JobDataMap中直接获取、在Job实现类中添加setter方法对应JobDataMap的键值
未完待续~~~
https://www.imooc.com/video/15144