综合百科

Quartz是什么

Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。

Quartz核心概念

Job:表示一个工作,要执行的具体内容,此接口中只有一个方法:void execute(JobExecutionContext context)

JobDetail:表示一个具体的可执行的调度程序,Job是这个可执行程序所需要执行的内容,另外,JobDetail还包含了这个任务调度的方案和策略。

Trigger:表示一个调度参数的配置,什么时候去调。

Scheduler:表示一个调度容器,一个调度容器中可以注册多个JobDetail 和 Trigger。

Quartz运行环境

Quartz可以运行嵌入在另一个独立式应用程序。

Quartz可以在应用程序服务器(或Servlet容器)内被实例化,并且参与XA事务。

Quartz可以作为一个独立的程序运行(其自己的JVM内),可以通过RMI使用。

Quartz可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行。

publicclassQuickstart{publicstaticvoidmain(String[]args){try{Schedulerscheduler=StdSchedulerFactory.getDefaultScheduler();scheduler.start();scheduler.shutdown();}catch(SchedulerExceptione){e.printStackTrace();}}}

运行日志如下:

14:53:00.764[main]INFOorg.quartz.impl.StdSchedulerFactory-UsingdefaultimplementationforThreadExecutor14:53:00.790[main]INFOorg.quartz.simpl.SimpleThreadPool-Jobexecutionthreadswilluseclassloaderofthread:main14:53:00.856[main]INFOorg.quartz.core.SchedulerSignalerImpl-InitializedSchedulerSignalleroftype:classorg.quartz.core.SchedulerSignalerImpl14:53:00.856[main]INFOorg.quartz.core.QuartzScheduler-QuartzSchedulerv.2.3.0created.14:53:00.857[main]INFOorg.quartz.simpl.RAMJobStore-RAMJobStoreinitialized.14:53:00.858[main]INFOorg.quartz.core.QuartzScheduler-Schedulermeta-data:QuartzScheduler(v2.3.0)'DefaultQuartzScheduler'withinstanceId'NON_CLUSTERED'Schedulerclass:'org.quartz.core.QuartzScheduler'-runninglocally.NOTSTARTED.Currentlyinstandbymode.Numberofjobsexecuted:0Usingthreadpool'org.quartz.simpl.SimpleThreadPool'-with10threads.Usingjob-store'org.quartz.simpl.RAMJobStore'-whichdoesnotsupportpersistence.andisnotclustered.14:53:00.858[main]INFOorg.quartz.impl.StdSchedulerFactory-Quartzscheduler'DefaultQuartzScheduler'initializedfromdefaultresourcefileinQuartzpackage:'quartz.properties'14:53:00.858[main]INFOorg.quartz.impl.StdSchedulerFactory-Quartzschedulerversion:2.3.014:53:00.859[main]INFOorg.quartz.core.QuartzScheduler-SchedulerDefaultQuartzScheduler_$_NON_CLUSTEREDstarted.14:53:00.859[main]INFOorg.quartz.core.QuartzScheduler-SchedulerDefaultQuartzScheduler_$_NON_CLUSTEREDshuttingdown.14:53:00.859[main]INFOorg.quartz.core.QuartzScheduler-SchedulerDefaultQuartzScheduler_$_NON_CLUSTEREDpaused.14:53:00.859[main]DEBUGorg.quartz.simpl.SimpleThreadPool-Shuttingdownthreadpool...14:53:00.859[main]DEBUGorg.quartz.simpl.SimpleThreadPool-Shutdownofthreadpoolcomplete.14:53:00.859[main]INFOorg.quartz.core.QuartzScheduler-SchedulerDefaultQuartzScheduler_$_NON_CLUSTEREDshutdowncomplete.14:53:01.303[DefaultQuartzScheduler_Worker-1]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.303[DefaultQuartzScheduler_Worker-2]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.304[DefaultQuartzScheduler_Worker-6]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.304[DefaultQuartzScheduler_Worker-5]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.305[DefaultQuartzScheduler_Worker-9]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.323[DefaultQuartzScheduler_Worker-3]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.338[DefaultQuartzScheduler_Worker-7]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.338[DefaultQuartzScheduler_Worker-8]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.338[DefaultQuartzScheduler_Worker-4]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.14:53:01.338[DefaultQuartzScheduler_Worker-10]DEBUGorg.quartz.simpl.SimpleThreadPool-WorkerThreadisshutdown.

Scheduler的生命周期

从SchedulerFactory创建它时开始,到Scheduler调用shutdown()方法时结束;Scheduler被创建后,可以增加、删除和列举Job和Trigger,以及执行它的与调度相关的操作,但是,Scheduler只有在调用start()方法后,才会真正地触发Trigger(即执行job)。

Job和Trigger的联系

一个Job就是实现了Job接口的类,当Job的一个Trigger被触发时,execute()方法由调用程序的一个工作线程调用,传递给execute()方法的JobExecutionContext对象向作业实例提供“运行时”环境,一个Job的Trigger被触发后,execute()方法会被Scheduler的一个工作线程调用,传递给execute()方法的JobExecutionContext对象中保存着该Job运行时的一些信息。

Trigger是用于触发Job执行的,当调度一个Job时,创建一个Trigger实例,设置调度相关的属性,Quartz自带了各种不同类型的Trigger,最常用的主要是SimpleTrigger和CronTrigger。

Job和Trigger的Key

将Job和Trigger注册到Scheduler时,可以为它们设置key,配置其身份属性,Job和Trigger的Key可以用于将Job和Trigger放到不同的分组里,然后基于分组进行操作。注意:同一个分组下的Job和Trigger的名称必须唯一,即一个Job或Trigger的Key由名称(name)和分组(group)组成。

问题:为什么既有Job又有Trigger呢?

很多任务调度器并不区分Job和Trigger,有些调度器只是简单地通过一个执行时间和一些Job标识符来定义一个Job;其它的一些调度器将Quartz的Job和Trigger对象合二为一。Quartz的开发者认为将调度和要调度的任务分离是合理的,例如:Job被创建后,可以保存在Scheduler中,与Trigger是独立的,同一个Job可以有多个Trigger,Job和Trigger之间是松耦合的,当与Scheduler中的Job关联的Trigger都过期了,可以配置Job稍后被重新调度,而不是重新定义Job,还有,可以修改或者替换Trigger,而不用重新定义与之关联的Job。

Job和JobDetail的联系

JobDetail实例是通过JobBuilder类创建的,在Quartz的描述语言中,JobDetail被称为“Job定义”或者“JobDetail实例”,一个正在执行的Job被称为“Job实例”,所以,当我们使用“Job”时,一般指代的是Job定义,或者JobDetail;当我们提到实现Job接口的类时,通常使用“Job类”。

Job状态与并发

Job的状态数据和并发性,有一些地方需要注意,在Job类上可以加上一些注解来避免问题:

@DisallowConcurrentExecution:将该注解加到Job类上,告诉Quartz不要并发地执行同一个Job定义,需要注意:该注解虽然加在Job类上,但实际上是作用在JobDetail上的。

@PersistJobDataAfterExecution:将该注解加到Job类上,告诉Quartz在成功执行了job类的execute方法后(没有发生任何异常),更新JobDetail中JobDataMap的数据,使得该Job(即JobDetail)在下一次执行的时候,JobDataMap中是更新后的数据,而不是更新前的旧数据。和 @DisallowConcurrentExecution注解一样,该注解虽然加在Job类上,但实际上是作用在JobDetail上的。

如果你使用了@PersistJobDataAfterExecution注解,我们强烈建议你同时使用@DisallowConcurrentExecution注解,因为当同一个Job(JobDetail)的两个实例被并发执行时,由于竞争,JobDataMap中存储的数据很可能是不确定的。

JobDataMap

JobDataMap是Java Map接口的一个实现,可以包含不限量的(序列化的)数据对象,在Job实例执行的时候,可以使用其中的数据。

如果使用持久化的存储机制,在决定JobDataMap中存放什么数据的时候需要小心,因为JobDataMap中存放的对象都会被序列化,因而可能会导致类的版本不一致的问题。

JobExecutionException

是execute方法中仅允许抛出一种类型的异常,在实际应用中,应该将execute方法中的所有内容都放到一个”try-catch”块中,以便知道如何来处理发生的异常。

快速开始的完整示例

publicclassQuickstart{publicstaticvoidmain(String[]args){try{Schedulerscheduler=StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetailjob=newJob(HelloJob.class).withIdentity("job1","group1").usingJobData("name","quartz").build();Triggertrigger=newTrigger().withIdentity("trigger1","group1").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(30).repeatForever()).build();scheduler.scheduleJob(job,trigger);try{Thread.sleep(1000L*60L*10L);}catch(InterruptedExceptione){e.printStackTrace();}scheduler.shutdown();}catch(SchedulerExceptione){e.printStackTrace();}}}publicclassHelloJobimplementsJob{@Overridepublicvoidexecute(JobExecutionContextcontext)throwsJobExecutionException{try{JobDetailjob=context.getJobDetail();Stringname=job.getJobDataMap().getString("name");System.out.println("hello"+name+"at"+newDate());}catch(Exceptione){e.printStackTrace();}}}

关于Quartz是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。