quartz,spring-quartz,spring-task,spring-schedule四者的区别:
quartz 是一个调度器,可以放任务进去,对任务指定时间执行。
spring-quartz 只是 spring 对 quartz 的一个包装而已。其实现是在 spring-context-support 中。
spring-task 完全是 spring 自己的调度实现,其代码是在 spring-context 中,有2种方式1种是 xml,另一种是注解形式。spring-task 也支持 cron 表达式
spring-schedule 就是 spring-task
简介
Quartz任务调度场景的核心分为以时间为关注点的调度和资源上的调度。
以时间为关注点的调度如:微博禁言一周、冻结用户账号,在一周之内不能登录等
资源上的调度如:每执行一个任务都要开一个线程,无限制的使用必然耗尽亏空,大多数系统都要对资源使用进行控制——首先服务线程的最大数目必须限制,其次可以考虑使用线程池以便共享服务的线程资源,降低频繁创建、销毁线程的消耗。
任务调度本身涉及到多线程并发、运行时间规则制定及解析、运行现场保持与恢复、线程池维护等诸多方面的工作。
Quartz的核心主要包括三部分:任务(Job)、触发器(Trigger)和调度器(Scheduler),其中Scheduler是整个系统框架的心脏和灵魂。
一、三个核心概念
调度器(scheduler),简介:搭配 Trigger和Job
任务(job),简介:做什么工作
触发器(trigger),简介:什么时候工作
二、主要用到的设计模式
Builder模式(创建jobdetail,trigger)
Factory模式(创建Scheduler)
组件模式
链式写法
三、重要组成
Job
JobDetail
JobDetail
JobStore
Trigger:SimpleTrigger、CronTrigger
TriggerBuilder:
ThreadPool:共享线程池,解决并发问题
Scheduler
Calendar:一个Trigger可以和多个Calendar关联,以排除或包含某些时间点
监听器:JobListener,TriggerListner,SchedulerListener
第一步:引入依赖:
org.quartz-scheduler
quartz
2.2.3
第二步:创建要被定执行的任务类
这一步也很简单,只需要创建一个实现了org.quartz.Job接口的类,并实现这个接口的唯一一个方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:
package com.how2java;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* 描述: MailJob 实现了 Job 接口,提供 execute,干具体的活儿
*/
public class MailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String email = detail.getJobDataMap().getString("email");
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String now = sdf.format(new Date());
System.out.printf("给邮件地址 %s 发出了一封定时邮件, 当前时间是: %s%n" ,email, now);
}
}
第三步:创建任务调度,并执行
package com.how2java;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
public class TestQuartz {
public static void main(String[] args) throws Exception{
//创建调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//定义一个触发器
Trigger trigger = newTrigger().withIdentity("trigger1", "group1") //定义名称和所属的组
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(2) //每隔2秒执行一次
.withRepeatCount(10)) //总共执行11次(第一次执行不基数)
.build();
//定义一个JobDetail
JobDetail job = newJob(MailJob.class) //指定干活的类MailJob
.withIdentity("mailjob1", "mailgroup") //定义任务名称和分组
.usingJobData("email", "admin@10086.com") //定义属性
.build();
//调度加入这个job
scheduler.scheduleJob(job, trigger);
//启动
scheduler.start();
//等待20秒,让前面的任务都执行完了之后,再关闭调度器
Thread.sleep(20000);
scheduler.shutdown(true);
}
}
分组干什么用?
.withIdentity("mailjob1", "mailgroup")
上面的 mailgroup 就是分组的意思。
比如一个系统有3个job 是备份数据库的,有4个job 是发邮件的,那么对他们进行分组,可以方便管理,类似于一次性停止所有发邮件的这样的操作。
静态导入
上面的导包 import static org.quartz. ,这种写法叫做静态导入,指的是导入某个类的静态方法, 这样就可以直接使用了,而不是必须写成:
JobBuilder.newJob()
浅谈Job—— Job实例在Quartz中的生命周期
每次调度器执行job时,它在调用execute()方法前会创建1个新的job实例。
当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。
参考来源于: