一般我们在什么情况下需要用到定时任务呢?
每隔时间段,或者某个时间点之后需要完成任务,这个时候就需要用到定时任务了。
比如我最近写的定时邮件功能,就是在每隔几天之后,对符合条件的邮箱发送邮件。使用quartz实现定时任务。
Quartz的基本组成部分
- 调度器:Scheduler
- 任务:JobDetail
- 触发器:Trigger,包括SimpleTrigger和CronTrigger
常用对象
JobExecutionContext:Job能通过 JobExecutionContext 访问 Quartz 运行环境以及 Job 的明细数据,当 Scheduler 调用 Job 时能将数据传递给 execute() 方法。
this.scheduler = scheduler;
this.trigger = firedBundle.getTrigger();
this.calendar = firedBundle.getCalendar();
this.jobDetail = firedBundle.getJobDetail();
this.job = job;
this.recovering = firedBundle.isRecovering();
this.fireTime = firedBundle.getFireTime();
this.scheduledFireTime = firedBundle.getScheduledFireTime();
this.prevFireTime = firedBundle.getPrevFireTime();
this.nextFireTime = firedBundle.getNextFireTime();
this.jobDataMap = new JobDataMap();
this.jobDataMap.putAll(this.jobDetail.getJobDataMap());
this.jobDataMap.putAll(this.trigger.getJobDataMap());
Job:一个接口,只有一个 execute(JobExecutionContext context) 方法,用于编写具体的任务业务逻辑。当调度器需要执行 job 时创建实例,调用完成后释放 job 实例。
JobDetail:描述 Job 实列的详细信息。name:job名称;group:job组。默认值为default;jobClass:job接口实现类的class;jobDataMap:存储Job实例的状态信息,调度器使用这些信息添加 Job 实例。
JobDataMap:是一个JDK中Map接口实例,在任务调度时存在于 JobExecutionContext 中,可将参数对象传递给在运行的 Job 实例;而且,它自身有方便的方法可存取基本数据类型。
Trigger:触发器,可设置首次被触发事件 startTime,不再被触发事件 endTime。
ScheduleBuilder:设置任务执行计划,如多久执行一次,是否重复执行,延迟多久执行等。
Scheduler:调度器,管理任务调取容器。
我从应用层面来说一下怎么构建这个接口。
首先我们需要定义实现一个定时功能的接口,我们可以称之为Task(或Job),如定时发送邮件的task(Job)
定义触发器,触发器Trigger最基本的功能是指定Job的执行时间,执行间隔,运行次数等。
然后创建scheduler,执行任务
public class MyScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
// 2、创建JobDetail实例,并与你自己写的Job类绑定(Job执行内容(execute))
JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
.withIdentity("job1", "group1").build();
// 3、构建Trigger实例,每隔1s执行一次
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
.startNow()//立即生效
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1)//每隔1s执行一次
.repeatForever()).build();//一直执行
//4、执行
scheduler.scheduleJob(jobDetail, trigger);
System.out.println("--------scheduler start ! ------------");
scheduler.start();
//睡眠
TimeUnit.MINUTES.sleep(1);
scheduler.shutdown();
System.out.println("--------scheduler shutdown ! ------------");
}
}