Quartz是一款由java写成的作业调度框架,在大量javase/javaee应用中被用来做定时任务,它功能强大而又不失使用简单性。
maven引入:
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.2</version> </dependency>
加入配置文件org/quartz/quartz.properties,使用源码包里面默认配置即可:
org.quartz.scheduler.instanceName: DefaultQuartzScheduler org.quartz.scheduler.rmi.export: false org.quartz.scheduler.rmi.proxy: false org.quartz.scheduler.wrapJobExecutionInUserTransaction: false org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount: 20 org.quartz.threadPool.threadPriority: 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
例子代码:
调度管理类:
import java.util.HashMap; import java.util.Map; import org.quartz.DateBuilder; import org.quartz.DateBuilder.IntervalUnit; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.SimpleTrigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class QuartzManager { private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory(); private static String HM_JOB = "HM_JOB"; private static String HM_TRIGGER = "HM_TRIGGER"; /** * 增加任务 * @param jobClass 任务实现类 * @param jobName 任务名称 * @param interval 间隔时间 * @param data 数据 */ public static void addJob(Class<? extends Job> jobClass, String jobName, int interval, Map<String, Object> data) { try { Scheduler sched = gSchedulerFactory.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(jobClass) .withIdentity(jobName, HM_JOB)//任务名称和组构成任务key .build(); jobDetail.getJobDataMap().putAll(data); // 触发器 SimpleTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(jobName, HM_TRIGGER)//触发器key .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND)) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(interval) .repeatForever()) .build(); sched.scheduleJob(jobDetail, trigger); // 启动 if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { e.printStackTrace(); } } /** * 删除任务 * * @param jobName 任务名称 */ public static void removeJob(String jobName) { try { Scheduler sched = gSchedulerFactory.getScheduler(); sched.deleteJob(new JobKey(jobName, HM_JOB)); } catch (Exception e) { e.printStackTrace(); } } }
实现Job自定义任务类:
import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class TestJob implements Job { public void execute(JobExecutionContext jobexecutioncontext) throws JobExecutionException { String id = jobexecutioncontext.getJobDetail().getJobDataMap().getString("id"); System.out.println("threadId: " + Thread.currentThread().getId() + ", id: " + id); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
main:
public static void main(String[] args) throws InterruptedException { Map<String, Object> map = new HashMap<String, Object>(); map.put("id", "1"); addJob(TestJob.class, "aaa", 1, map); map.clear(); map.put("id", "2"); addJob(TestJob.class, "bbb", 1, map); Thread.sleep(3000); removeJob("aaa"); System.out.println("main end----------"); Thread.sleep(3000); System.exit(1); }
结果:
threadId: 12, id: 2 threadId: 11, id: 1 threadId: 13, id: 1 threadId: 14, id: 2 threadId: 15, id: 1 threadId: 16, id: 2 main end---------- threadId: 17, id: 2 threadId: 18, id: 2 threadId: 19, id: 2
Quartz是通过对用户暴露出Scheduler来进行任务的操作,它可以把任务JobDetail和触发器Trigger加入任务池中,可以把任务删除,也可以把任务停止,scheduler把这些任务和触发器放到一个JobStore中,这里jobStore有内存形式的也有持久化形式的,当然也可以自定义扩展成独立的服务。
它内部会通过一个调度线程QuartzSchedulerThread不断到JobStore中找出下次需要执行的任务,并把这些任务封装放到一个线程池ThreadPool中运行,它的组件结构如下图:
1.Job就是自定义业务的接口,里面就一个execute方法,线程运行Job时会把JobDataMap封装到JobExecutionContext里作为execute方法的参数,jobdetail是对job的封装,里面有Job的class,对应的数据, 名称,分组等
2.Trigger是触发器,job下次什么时候执行存放在trigger中
3.QuartzSchedulerResources相当于调度的资源存放器,包含了JobStore, ThreadPool等资源,调度都是通过 QuartzSchedulerResources获取相关属性的。
4.jobStore是任务和触发器存储地方,它里面提供大量类似于增删改的操作任务方法。
5.QuartzSchedulerThread是一个调度线程,ThreadPool是一个执行线程池,下图是运行后的线程栈: