您好,登錄后才能下訂單哦!
這篇文章給大家介紹Quartz是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Quartz是一個(gè)完全由Java編寫的開源作業(yè)調(diào)度框架,為在Java應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡單卻強(qiáng)大的機(jī)制。
Quartz核心概念
Job:表示一個(gè)工作,要執(zhí)行的具體內(nèi)容,此接口中只有一個(gè)方法:void execute(JobExecutionContext context)
JobDetail:表示一個(gè)具體的可執(zhí)行的調(diào)度程序,Job是這個(gè)可執(zhí)行程序所需要執(zhí)行的內(nèi)容,另外,JobDetail還包含了這個(gè)任務(wù)調(diào)度的方案和策略。
Trigger:表示一個(gè)調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。
Scheduler:表示一個(gè)調(diào)度容器,一個(gè)調(diào)度容器中可以注冊多個(gè)JobDetail 和 Trigger。
Quartz運(yùn)行環(huán)境
Quartz可以運(yùn)行嵌入在另一個(gè)獨(dú)立式應(yīng)用程序。
Quartz可以在應(yīng)用程序服務(wù)器(或Servlet容器)內(nèi)被實(shí)例化,并且參與XA事務(wù)。
Quartz可以作為一個(gè)獨(dú)立的程序運(yùn)行(其自己的JVM內(nèi)),可以通過RMI使用。
Quartz可以被實(shí)例化,作為獨(dú)立的項(xiàng)目集群(負(fù)載平衡和故障轉(zhuǎn)移功能),用于作業(yè)的執(zhí)行。
public class Quickstart { public static void main(String[] args) { try { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); scheduler.shutdown(); } catch (SchedulerException e) { e.printStackTrace(); } } }
運(yùn)行日志如下:
14:53:00.764 [main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor 14:53:00.790 [main] INFO org.quartz.simpl.SimpleThreadPool - Job execution threads will use class loader of thread: main 14:53:00.856 [main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 14:53:00.856 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created. 14:53:00.857 [main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized. 14:53:00.858 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads. Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered. 14:53:00.858 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 14:53:00.858 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0 14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. 14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down. 14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused. 14:53:00.859 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutting down threadpool... 14:53:00.859 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutdown of threadpool complete. 14:53:00.859 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete. 14:53:01.303 [DefaultQuartzScheduler_Worker-1] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.303 [DefaultQuartzScheduler_Worker-2] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.304 [DefaultQuartzScheduler_Worker-6] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.304 [DefaultQuartzScheduler_Worker-5] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.305 [DefaultQuartzScheduler_Worker-9] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.323 [DefaultQuartzScheduler_Worker-3] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.338 [DefaultQuartzScheduler_Worker-7] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.338 [DefaultQuartzScheduler_Worker-8] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.338 [DefaultQuartzScheduler_Worker-4] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 14:53:01.338 [DefaultQuartzScheduler_Worker-10] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down.
Scheduler的生命周期
從SchedulerFactory創(chuàng)建它時(shí)開始,到Scheduler調(diào)用shutdown()方法時(shí)結(jié)束;Scheduler被創(chuàng)建后,可以增加、刪除和列舉Job和Trigger,以及執(zhí)行它的與調(diào)度相關(guān)的操作,但是,Scheduler只有在調(diào)用start()方法后,才會(huì)真正地觸發(fā)Trigger(即執(zhí)行job)。
Job和Trigger的聯(lián)系
一個(gè)Job就是實(shí)現(xiàn)了Job接口的類,當(dāng)Job的一個(gè)Trigger被觸發(fā)時(shí),execute()方法由調(diào)用程序的一個(gè)工作線程調(diào)用,傳遞給execute()方法的JobExecutionContext對象向作業(yè)實(shí)例提供“運(yùn)行時(shí)”環(huán)境,一個(gè)Job的Trigger被觸發(fā)后,execute()方法會(huì)被Scheduler的一個(gè)工作線程調(diào)用,傳遞給execute()方法的JobExecutionContext對象中保存著該Job運(yùn)行時(shí)的一些信息。
Trigger是用于觸發(fā)Job執(zhí)行的,當(dāng)調(diào)度一個(gè)Job時(shí),創(chuàng)建一個(gè)Trigger實(shí)例,設(shè)置調(diào)度相關(guān)的屬性,Quartz自帶了各種不同類型的Trigger,最常用的主要是SimpleTrigger和CronTrigger。
Job和Trigger的Key
將Job和Trigger注冊到Scheduler時(shí),可以為它們設(shè)置key,配置其身份屬性,Job和Trigger的Key可以用于將Job和Trigger放到不同的分組里,然后基于分組進(jìn)行操作。注意:同一個(gè)分組下的Job和Trigger的名稱必須唯一,即一個(gè)Job或Trigger的Key由名稱(name)和分組(group)組成。
問題:為什么既有Job又有Trigger呢?
很多任務(wù)調(diào)度器并不區(qū)分Job和Trigger,有些調(diào)度器只是簡單地通過一個(gè)執(zhí)行時(shí)間和一些Job標(biāo)識(shí)符來定義一個(gè)Job;其它的一些調(diào)度器將Quartz的Job和Trigger對象合二為一。Quartz的開發(fā)者認(rèn)為將調(diào)度和要調(diào)度的任務(wù)分離是合理的,例如:Job被創(chuàng)建后,可以保存在Scheduler中,與Trigger是獨(dú)立的,同一個(gè)Job可以有多個(gè)Trigger,Job和Trigger之間是松耦合的,當(dāng)與Scheduler中的Job關(guān)聯(lián)的Trigger都過期了,可以配置Job稍后被重新調(diào)度,而不是重新定義Job,還有,可以修改或者替換Trigger,而不用重新定義與之關(guān)聯(lián)的Job。
Job和JobDetail的聯(lián)系
JobDetail實(shí)例是通過JobBuilder類創(chuàng)建的,在Quartz的描述語言中,JobDetail被稱為“Job定義”或者“JobDetail實(shí)例”,一個(gè)正在執(zhí)行的Job被稱為“Job實(shí)例”,所以,當(dāng)我們使用“Job”時(shí),一般指代的是Job定義,或者JobDetail;當(dāng)我們提到實(shí)現(xiàn)Job接口的類時(shí),通常使用“Job類”。
Job狀態(tài)與并發(fā)
Job的狀態(tài)數(shù)據(jù)和并發(fā)性,有一些地方需要注意,在Job類上可以加上一些注解來避免問題:
@DisallowConcurrentExecution:將該注解加到Job類上,告訴Quartz不要并發(fā)地執(zhí)行同一個(gè)Job定義,需要注意:該注解雖然加在Job類上,但實(shí)際上是作用在JobDetail上的。
@PersistJobDataAfterExecution:將該注解加到Job類上,告訴Quartz在成功執(zhí)行了job類的execute方法后(沒有發(fā)生任何異常),更新JobDetail中JobDataMap的數(shù)據(jù),使得該Job(即JobDetail)在下一次執(zhí)行的時(shí)候,JobDataMap中是更新后的數(shù)據(jù),而不是更新前的舊數(shù)據(jù)。和 @DisallowConcurrentExecution注解一樣,該注解雖然加在Job類上,但實(shí)際上是作用在JobDetail上的。
如果你使用了@PersistJobDataAfterExecution注解,我們強(qiáng)烈建議你同時(shí)使用@DisallowConcurrentExecution注解,因?yàn)楫?dāng)同一個(gè)Job(JobDetail)的兩個(gè)實(shí)例被并發(fā)執(zhí)行時(shí),由于競爭,JobDataMap中存儲(chǔ)的數(shù)據(jù)很可能是不確定的。
JobDataMap
JobDataMap是Java Map接口的一個(gè)實(shí)現(xiàn),可以包含不限量的(序列化的)數(shù)據(jù)對象,在Job實(shí)例執(zhí)行的時(shí)候,可以使用其中的數(shù)據(jù)。
如果使用持久化的存儲(chǔ)機(jī)制,在決定JobDataMap中存放什么數(shù)據(jù)的時(shí)候需要小心,因?yàn)镴obDataMap中存放的對象都會(huì)被序列化,因而可能會(huì)導(dǎo)致類的版本不一致的問題。
JobExecutionException
是execute方法中僅允許拋出一種類型的異常,在實(shí)際應(yīng)用中,應(yīng)該將execute方法中的所有內(nèi)容都放到一個(gè)”try-catch”塊中,以便知道如何來處理發(fā)生的異常。
快速開始的完整示例
public class Quickstart { public static void main(String[] args) { try { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1") .usingJobData("name", "quartz").build(); Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow() .withSchedule(simpleSchedule().withIntervalInSeconds(30).repeatForever()).build(); scheduler.scheduleJob(job, trigger); try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { e.printStackTrace(); } scheduler.shutdown(); } catch (SchedulerException e) { e.printStackTrace(); } } } public class HelloJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { JobDetail job = context.getJobDetail(); String name = job.getJobDataMap().getString("name"); System.out.println("hello " + name + " at " + new Date()); } catch (Exception e) { e.printStackTrace(); } } }
關(guān)于Quartz是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。