淮安做網(wǎng)站的有多少站長之家音效
一、Quartz介紹
Quartz [kw??ts] 是OpenSymphony開源組織在Job scheduling領(lǐng)域又一個開源項(xiàng)目,完全由Java開發(fā),可以用來執(zhí)行定時任務(wù),類似于java.util.Timer。但是相較于Timer, Quartz增加了很多功能:
1.持久性作業(yè) - 就是保持調(diào)度定時的狀態(tài);
2.作業(yè)管理 - 對調(diào)度作業(yè)進(jìn)行有效的管理;
Quartz是一個強(qiáng)大任務(wù)調(diào)度框架,可以用來干嘛?
簡單來說就是實(shí)現(xiàn)“計(jì)劃(或定時)任務(wù)”的系統(tǒng),例如:
訂單下單后未付款,15分鐘后自動撤消訂單,并自動解鎖鎖定的商品;
一個OA系統(tǒng)需要在每周五9點(diǎn)自動生成數(shù)據(jù)報表;
比如vip的每月自動續(xù)費(fèi)功能;
或者想每月10號自動還款;
又或者每周給暗戀的女生定時發(fā)送郵件等等。
Java 語言實(shí)現(xiàn)定時任務(wù)的幾種方式
java.util.Timer:一個 JDK 中自帶的處理簡單定時任務(wù)的工具。
java.util.concurrent.ScheduledExecutorService:JDK 中的定時任務(wù)接口,可以將定時任務(wù)與線程池功能結(jié)合使用。
org.springframework.scheduling.annotation.Scheduled:Spring 框架中基于注解來實(shí)現(xiàn)定時任務(wù)處理。
Quartz:一個完全由 Java 語言編寫的,支持分布式調(diào)度任務(wù)的開源框架。
二、Quartz的核心概念
三大核心類 JObDetail(作業(yè)類),Trigger(觸發(fā)器),Scheduler(調(diào)度器)。Trigger指定JObDetail什么時候發(fā)布任務(wù)。
1,任務(wù)job
job就是你想實(shí)現(xiàn)的任務(wù)類,每一個job必須實(shí)現(xiàn)org.quartz.job接口,且只需實(shí)現(xiàn)接口定義的execute()方法。
Job:工作任務(wù)調(diào)度的接口,任務(wù)類需要實(shí)現(xiàn)該接口,該接口中定義execute方法,類似jdk提供的TimeTask類的run方法,在里面編寫任務(wù)執(zhí)行的業(yè)務(wù)邏輯。
Job:實(shí)例在Quartz中的生命周期,每次調(diào)度器執(zhí)行job時它在調(diào)用execute方法前,會創(chuàng)建一個新的job實(shí)例,當(dāng)調(diào)用完成后,關(guān)聯(lián)的job對象實(shí)例會被是釋放,釋放的實(shí)例會被垃圾回收機(jī)制回收。
2,觸發(fā)器Trigger
Trigger 為你執(zhí)行任務(wù)的觸發(fā)器,比如你想每天定時1點(diǎn)發(fā)送郵件,Trigger將會設(shè)置1點(diǎn)執(zhí)行該任務(wù)。
Trigger主要包含兩種:SimpleTrigger和CronTriggerr。
3,調(diào)度器Scheduler
Scheduler是任務(wù)的調(diào)度器,會將任務(wù)job和觸發(fā)器TRigger結(jié)合,負(fù)責(zé)基于Trigger設(shè)定的時間執(zhí)行job。
三、Quartz的幾個常用API
Scheduler :用于與調(diào)度程序交互的主程序接口。
Job :預(yù)先定義的希望在未來時間被調(diào)度程序執(zhí)行的任務(wù)類,自定義。
JobDetall :使用JobDetail來定義定時任務(wù)的實(shí)例,JobDetail實(shí)例是通過JobBuilder類創(chuàng)建。
JobDataMap :可包含數(shù)據(jù)對象,在job實(shí)例執(zhí)行的是好,可使用包含的數(shù)據(jù);JobDataMap是java Map接口的實(shí)現(xiàn),增加了一些存取基本類型方法。
Trgger觸發(fā)器 :Trigger對象是用于觸發(fā)執(zhí)行Job的,當(dāng)調(diào)度一個Job時,我們實(shí)例一個觸發(fā)器然后調(diào)整它的屬性來滿足Job執(zhí)行的條件,表明任務(wù)在什么時候執(zhí)行。定義了一個已經(jīng)被安排的任務(wù)將在什么時候執(zhí)行的時間條件,比如每秒執(zhí)行一次。
JobBuilder :用于聲明一個任務(wù)實(shí)例,也可以定義關(guān)于該任務(wù)的詳情比如:任務(wù)名,組名等,這個聲明的實(shí)例將作為一個實(shí)例執(zhí)行的任務(wù)。
TriggerBuilder :觸發(fā)器創(chuàng)建器,用于創(chuàng)建觸發(fā)器trigger實(shí)例。
JobListener,TriggerListener,SchedulerListener監(jiān)聽器,用于對組件的監(jiān)聽。
四、Quartz的簡單使用
運(yùn)行程序,可以看到程序每隔1s會打印出內(nèi)容,且在12s后程序結(jié)束。
創(chuàng)建項(xiàng)目并加入依賴,參考:【普通的IDEA maven java項(xiàng)目demo(hello word)-1.8】待更新CSDN鏈接
<dependency>
??? <groupId>org.quartz-scheduler</groupId>
??? <artifactId>quartz</artifactId>
??? <version>2.3.2</version>
</dependency>
?
新建一個能夠打印任意內(nèi)容的Job:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
?
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
?
public class PrintWordsJob implements Job {
??? @Override
??? public void execute(JobExecutionContext jobExecutionContext) {
??????? String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date());
??????? System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));
??? }
}
?
創(chuàng)建Schedule,執(zhí)行任務(wù):
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
?
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
?
public class Demo {
?
??? public static void main(String[] args) throws SchedulerException, InterruptedException {
?
??????? // 1、創(chuàng)建JobDetail實(shí)例,并與PrintWordsJob類綁定(Job執(zhí)行內(nèi)容)
??????? JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
??????????????? .withIdentity("job1", "group1").build();
?
??????? // 2、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次
??????? Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
??????????????? .startNow()// 立即生效
??????????????? .withSchedule(SimpleScheduleBuilder.simpleSchedule()
??????????????????????? .withIntervalInSeconds(1)// 每隔1s執(zhí)行一次
??????????????????????? .repeatForever()).build();// 一直執(zhí)行
?
??????? // 3、創(chuàng)建調(diào)度器Scheduler并執(zhí)行
??????? Scheduler scheduler = new StdSchedulerFactory().getScheduler();
??????? scheduler.scheduleJob(jobDetail, trigger);
??????? System.out.println("--------scheduler start ! ------------");
??????? System.out.println("at:" + new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date()) + ", prints: Hello scheduler");
??????? scheduler.start();
?
??????? // 睡眠12秒
??????? TimeUnit.MILLISECONDS.sleep(12000);
??????? scheduler.shutdown();
??????? System.out.println("at:" + new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date()) + ", prints: Hello scheduler");
??????? System.out.println("--------scheduler shutdown ! ------------");
??? }
}
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 00-05-01:123, prints: Hello scheduler
PrintWordsJob start at:23-08-22 00-05-01:129, prints: Hello Job-69
PrintWordsJob start at:23-08-22 00-05-02:052, prints: Hello Job-68
PrintWordsJob start at:23-08-22 00-05-03:057, prints: Hello Job-93
PrintWordsJob start at:23-08-22 00-05-04:061, prints: Hello Job-32
PrintWordsJob start at:23-08-22 00-05-05:057, prints: Hello Job-14
PrintWordsJob start at:23-08-22 00-05-06:051, prints: Hello Job-55
PrintWordsJob start at:23-08-22 00-05-07:058, prints: Hello Job-30
PrintWordsJob start at:23-08-22 00-05-08:048, prints: Hello Job-82
PrintWordsJob start at:23-08-22 00-05-09:058, prints: Hello Job-28
PrintWordsJob start at:23-08-22 00-05-10:059, prints: Hello Job-97
PrintWordsJob start at:23-08-22 00-05-11:053, prints: Hello Job-88
PrintWordsJob start at:23-08-22 00-05-12:048, prints: Hello Job-18
PrintWordsJob start at:23-08-22 00-05-13:057, prints: Hello Job-93
at:23-08-22 00-05-13:135, prints: Hello scheduler
--------scheduler shutdown ! ------------
五、Quartz核心詳解
1.Job和JobDetail
Job是Quartz中的一個接口,接口下只有execute方法,在這個方法中編寫業(yè)務(wù)邏輯。
JobDetail用來綁定Job,為Job實(shí)例提供許多屬性:name、group、jobClass、jobDataMap
JobDetail綁定指定的Job,每次Scheduler調(diào)度執(zhí)行一個Job的時候,首先會拿到對應(yīng)的Job,然后創(chuàng)建該Job實(shí)例,再去執(zhí)行Job中的execute()的內(nèi)容,任務(wù)執(zhí)行結(jié)束后,關(guān)聯(lián)的Job對象實(shí)例會被釋放,且會被JVM GC清除。
為什么設(shè)計(jì)成JobDetail + Job,不直接使用Job?
JobDetail定義的是任務(wù)數(shù)據(jù),而真正的執(zhí)行邏輯是在Job中。 這是因?yàn)槿蝿?wù)是有可能并發(fā)執(zhí)行,如果Scheduler直接使用Job,就會存在對同一個Job實(shí)例并發(fā)訪問的問題。而JobDetail & Job 方式,Sheduler每次執(zhí)行,都會根據(jù)JobDetail創(chuàng)建一個新的Job實(shí)例,這樣就可以規(guī)避并發(fā)訪問的問題。
2.Trigger、SimpleTrigger、CronTrigger
Trigger
Trigger是Quartz的觸發(fā)器,會去通知Scheduler何時去執(zhí)行對應(yīng)Job。
new Trigger().startAt():表示觸發(fā)器首次被觸發(fā)的時間;
new Trigger().endAt():表示觸發(fā)器結(jié)束觸發(fā)的時間;
SimpleTrigger
??SimpleTrigger可以實(shí)現(xiàn)在一個指定時間段內(nèi)執(zhí)行一次作業(yè)任務(wù)或一個時間段內(nèi)多次執(zhí)行作業(yè)任務(wù)。
?
將下述代碼替換上述【Quartz的簡單使用】代碼的 // 2、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次 內(nèi)容
程序運(yùn)行5s后開始執(zhí)行Job,執(zhí)行Job 5s后,再延時2s結(jié)束程序:
// 2、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次
??????? Date startDate = new Date();
??????? startDate.setTime(startDate.getTime() + 5000);
?
??????? Date endDate = new Date();
??????? endDate.setTime(startDate.getTime() + 5000);
?
??????? Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
??????????????? .usingJobData("trigger1", "這是jobDetail1的trigger")
??????????????? .startNow()//立即生效
??????????????? .startAt(startDate)
??????????????? .endAt(endDate)
??????????????? .withSchedule(SimpleScheduleBuilder.simpleSchedule()
??????????????????????? .withIntervalInSeconds(1)// 每隔1s執(zhí)行一次
??????????????????????? .repeatForever()).build();// 一直執(zhí)行
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 00-08-34:658, prints: Hello scheduler
PrintWordsJob start at:23-08-22 00-08-39:573, prints: Hello Job-81
PrintWordsJob start at:23-08-22 00-08-40:553, prints: Hello Job-63
PrintWordsJob start at:23-08-22 00-08-41:560, prints: Hello Job-87
PrintWordsJob start at:23-08-22 00-08-42:562, prints: Hello Job-25
PrintWordsJob start at:23-08-22 00-08-43:554, prints: Hello Job-65
at:23-08-22 00-08-46:666, prints: Hello scheduler
--------scheduler shutdown ! ------------
CronTrigger
??CronTrigger功能非常強(qiáng)大,是基于日歷的作業(yè)調(diào)度,而SimpleTrigger是精準(zhǔn)指定間隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表達(dá)式的,了解Cron表達(dá)式可參考:【cron表達(dá)式 詳解】cron表達(dá)式 詳解_linux cron表達(dá)式_西晉的no1的博客-CSDN博客
在線生成corn表達(dá)式: 在線Cron表達(dá)式生成器
將下述代碼替換上述【Quartz的簡單使用】代碼的 // 2、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次 內(nèi)容
從0秒開始,每5秒執(zhí)行一次定時任務(wù)
??????? // 2.觸發(fā)器
??????? CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger", "group").startNow()//立刻執(zhí)行
??????????????? .usingJobData("trigger1", "這是jobDetail1的trigger")
??????????????? .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ? *"))//表示每次0秒時候執(zhí)行。
??????????????? .build();
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 00-21-35:870, prints: Hello scheduler
PrintWordsJob start at:23-08-22 00-21-35:877, prints: Hello Job-39
PrintWordsJob start at:23-08-22 00-21-40:001, prints: Hello Job-68
PrintWordsJob start at:23-08-22 00-21-45:002, prints: Hello Job-8
at:23-08-22 00-21-47:873, prints: Hello scheduler
--------scheduler shutdown ! ------------
六、JobListener
創(chuàng)建MyJobListener實(shí)現(xiàn)JobListener接口
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
?
public class MyJobListener implements JobListener {
?
?
??? public String getName() {
??????? return this.getClass().getSimpleName();
??? }
?
??? //Scheduler在jobDetail將要被執(zhí)行時調(diào)用這個方法(執(zhí)行前)
??? public void jobToBeExecuted(JobExecutionContext context) {
??????? String jobName = context.getJobDetail().getKey().getName();
??????? System.out.println("我的job名1:" + jobName);
??? }
?
??? //Scheduler在jobDetail即將被執(zhí)行,但又被TriggerListermer 否定時會調(diào)用該方法
??? public void jobExecutionVetoed(JobExecutionContext context) {
??????? String jobName = context.getJobDetail().getKey().getName();
??????? System.out.println("我的job名2:" + jobName);
??? }
?
??? //Scheduler在jobDetail即將被執(zhí)行之后調(diào)用這個方法。(執(zhí)行后)
??? public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
??????? String jobName = context.getJobDetail().getKey().getName();
??????? System.out.println("我的job名3:" + jobName);
??? }
}
在scheduler創(chuàng)建后加入監(jiān)聽即可生效
scheduler.getListenerManager().addJobListener(new MyJobListener());
將下述藍(lán)色代碼放于上述【Quartz的簡單使用】對應(yīng)位置
// 3、創(chuàng)建調(diào)度器Scheduler并執(zhí)行
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.getListenerManager().addJobListener(new MyJobListener());
scheduler.scheduleJob(jobDetail, trigger);
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 00-28-12:174, prints: Hello scheduler
我的job名1:job1
PrintWordsJob start at:23-08-22 00-28-12:179, prints: Hello Job-7
我的job名3:job1
我的job名1:job1
PrintWordsJob start at:23-08-22 00-28-13:112, prints: Hello Job-39
我的job名3:job1
我的job名1:job1
…
…
…
PrintWordsJob start at:23-08-22 00-28-23:111, prints: Hello Job-0
我的job名3:job1
我的job名1:job1
PrintWordsJob start at:23-08-22 00-28-24:115, prints: Hello Job-12
我的job名3:job1
at:23-08-22 00-28-24:179, prints: Hello scheduler
--------scheduler shutdown ! ------------
七、TriggerListener
任務(wù)調(diào)度過程中,與觸發(fā)器Trigger相關(guān)的事件包括:觸發(fā)器觸發(fā),觸發(fā)器未正常觸發(fā),觸發(fā)器完成等。
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;
?
public class MyTriggerListener implements TriggerListener {
??? //用于獲取觸發(fā)器的名稱
??? public String getName() {//獲取默認(rèn)類名
??????? return this.getClass().getSimpleName();
??? }
?
??? //當(dāng)與監(jiān)聽器相關(guān)聯(lián)的trigger被觸發(fā),job上的execute()方法將被執(zhí)行時,Scheduler就調(diào)用該方法
??? public void triggerFired(Trigger trigger, JobExecutionContext context) {
??????? System.out.println("triggerFired");
??? }
?
??? //在Trigger觸發(fā)后,job將要被執(zhí)行時由Scheduler調(diào)用這個方法。
??? //TriggerListener給一個選擇去否決job的執(zhí)行。如方法返回true,job此次將不會為trigger觸發(fā)執(zhí)行。false,放行。
??? public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
??????? System.out.println("vetoJobExecution");
??????? return false;
??? }
?
??? //Scheduler 調(diào)用這個方法是在trigger錯過時觸發(fā)。
??? public void triggerMisfired(Trigger trigger) {
??????? System.out.println("triggerMisfired");
??? }
?
??? //triggerComplete:trigger被觸發(fā)并且完成了job的執(zhí)行時,Scheduler調(diào)用這個方法。
??? public void triggerComplete(Trigger trigger, JobExecutionContext context,
??????????????????????????????? Trigger.CompletedExecutionInstruction triggerInstructionCode) {
??????? System.out.println("triggerComplete");
??? }
?
}
將下述藍(lán)色代碼放于上述【Quartz的簡單使用】對應(yīng)位置
// 3、創(chuàng)建調(diào)度器Scheduler并執(zhí)行
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.getListenerManager().addTriggerListener(new MyTriggerListener());
scheduler.scheduleJob(jobDetail, trigger);
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 00-34-56:592, prints: Hello scheduler
triggerFired
vetoJobExecution
PrintWordsJob start at:23-08-22 00-34-56:601, prints: Hello Job-69
triggerComplete
triggerFired
vetoJobExecution
…
…
…
PrintWordsJob start at:23-08-22 00-35-07:530, prints: Hello Job-13
triggerComplete
triggerFired
vetoJobExecution
PrintWordsJob start at:23-08-22 00-35-08:535, prints: Hello Job-21
triggerComplete
at:23-08-22 00-35-08:597, prints: Hello scheduler
--------scheduler shutdown ! ------------
八、SchedulerListener
SchedulerListener會在scheduler的生命周期中關(guān)鍵事件發(fā)生時被調(diào)用,與Scheduler有關(guān)事件;增加或者刪除一個 job/trigger,關(guān)閉scheduler等。
import org.quartz.*;
?
public class MySchedulerListener implements SchedulerListener {
?
??? //用于部署JobDetail 的時候調(diào)用
??? public void jobScheduled(Trigger trigger) {
??????? String name = trigger.getKey().getName();
??????? System.out.println("獲取觸發(fā)器名稱:" + name);
??? }
?
??? //卸載JobDetail 的時候調(diào)用
??? public void jobUnscheduled(TriggerKey triggerKey) {
??????? System.out.println(triggerKey.getName());
??? }
?
??? //當(dāng)trigger來到再也不會觸發(fā)的時候調(diào)用這個方法
??? public void triggerFinalized(Trigger trigger) {
??????? String name = trigger.getKey().getName();
??????? System.out.println("獲取觸發(fā)器名稱:" + name);
??? }
?
??? //當(dāng)trigger 被暫停時候調(diào)用
??? public void triggerPaused(TriggerKey triggerKey) {
??????? System.out.println("被暫停1");
??? }
?
??? //當(dāng)trigger組? 被暫停時候調(diào)用
??? public void triggersPaused(String triggerGroup) {
??????? System.out.println("被暫停2");
??? }
?
??? ///當(dāng)trigger從? 被暫停 到恢復(fù) 時候 調(diào)用
??? public void triggerResumed(TriggerKey triggerKey) {
??????? System.out.println("恢復(fù)");
??? }
?
??? ///當(dāng)trigger組從? 被暫停 到恢復(fù) 時候 調(diào)用
??? public void triggersResumed(String triggerGroup) {
??????? System.out.println("恢復(fù)");
??? }
?
??? //添加工作任務(wù)調(diào)用
??? public void jobAdded(JobDetail jobDetail) {
??????? System.out.println("添加工作任務(wù)");
?
??? }
?
??? //刪除工作任務(wù)
??? public void jobDeleted(JobKey jobKey) {
??????? System.out.println("刪除工作任務(wù)");
?
??? }
?
??? public void jobPaused(JobKey jobKey) {
??????? // TODO Auto-generated method stub
?
??? }
?
??? public void jobsPaused(String jobGroup) {
??????? // TODO Auto-generated method stub
?
??? }
?
??? public void jobResumed(JobKey jobKey) {
??????? // TODO Auto-generated method stub
?
??? }
?
??? public void jobsResumed(String jobGroup) {
??????? // TODO Auto-generated method stub
?
??? }
?
??? //scheduler產(chǎn)生Error調(diào)用
??? public void schedulerError(String msg, SchedulerException cause) {
??????? // TODO Auto-generated method stub
?
??? }
?
??? //scheduler被掛起時候調(diào)用
??? public void schedulerInStandbyMode() {
??????? // TODO Auto-generated method stub
?
??? }
?
??? //scheduler開啟的時候調(diào)用
??? public void schedulerStarted() {
??????? System.out.println("scheduler 開啟 的時候調(diào)用");
?
??? }
?
??? //scheduler 正在開啟的時候調(diào)用 ing.....
??? public void schedulerStarting() {
??????? System.out.println("scheduler 正在開啟的時候調(diào)用 ing.....");
?
??? }
?
??? // scheduler關(guān)閉 的時候調(diào)用
??? public void schedulerShutdown() {
??????? System.out.println("scheduler關(guān)閉 的時候調(diào)用");
?
??? }
?
??? //scheduler 正在關(guān)閉的時候調(diào)用 ing.....
??? public void schedulerShuttingdown() {
??????? System.out.println("//scheduler 正在關(guān)閉的時候調(diào)用 ing.....");
?
??? }
?
??? //scheduler 數(shù)據(jù)被清除了的時候調(diào)用
??? public void schedulingDataCleared() {
??????? System.out.println("//scheduler 數(shù)據(jù)被清除了的時候調(diào)用");
?
??? }
?
}
將下述藍(lán)色代碼放于上述【Quartz的簡單使用】對應(yīng)位置
// 3、創(chuàng)建調(diào)度器Scheduler并執(zhí)行
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
scheduler.scheduleJob(jobDetail, trigger);
運(yùn)行結(jié)果(注意看時間):
添加工作任務(wù)
獲取觸發(fā)器名稱:trigger1
--------scheduler start ! ------------
at:23-08-22 00-37-43:391, prints: Hello scheduler
scheduler 正在開啟的時候調(diào)用 ing.....
scheduler 開啟 的時候調(diào)用
PrintWordsJob start at:23-08-22 00-37-43:395, prints: Hello Job-74
PrintWordsJob start at:23-08-22 00-37-44:294, prints: Hello Job-62
PrintWordsJob start at:23-08-22 00-37-45:301, prints: Hello Job-84
PrintWordsJob start at:23-08-22 00-37-46:292, prints: Hello Job-19
PrintWordsJob start at:23-08-22 00-37-47:301, prints: Hello Job-82
PrintWordsJob start at:23-08-22 00-37-48:288, prints: Hello Job-42
PrintWordsJob start at:23-08-22 00-37-49:296, prints: Hello Job-19
PrintWordsJob start at:23-08-22 00-37-50:298, prints: Hello Job-4
PrintWordsJob start at:23-08-22 00-37-51:290, prints: Hello Job-10
PrintWordsJob start at:23-08-22 00-37-52:294, prints: Hello Job-78
PrintWordsJob start at:23-08-22 00-37-53:292, prints: Hello Job-42
PrintWordsJob start at:23-08-22 00-37-54:298, prints: Hello Job-49
PrintWordsJob start at:23-08-22 00-37-55:291, prints: Hello Job-13
//scheduler 正在關(guān)閉的時候調(diào)用 ing.....
scheduler關(guān)閉 的時候調(diào)用
at:23-08-22 00-37-55:397, prints: Hello scheduler
--------scheduler shutdown ! ------------
九、定時任務(wù)參數(shù)傳遞問題
將下述藍(lán)色代碼放于上述【Quartz的簡單使用】1和2之間的位置
// 1、創(chuàng)建JobDetail實(shí)例,并與PrintWordsJob類綁定(Job執(zhí)行內(nèi)容)
JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
???????? .withIdentity("job1", "group1").build();
// 傳參
JobDataMap jobDataMap=jobDetail.getJobDataMap();
jobDataMap.put("name","傳參test");
jobDataMap.put("age",11);
jobDataMap.put("sex","男");
?
// 2、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
??????? .startNow()// 立即生效
??????? .withSchedule(SimpleScheduleBuilder.simpleSchedule()
??????????????? .withIntervalInSeconds(1)// 每隔1s執(zhí)行一次
??????????????? .repeatForever()).build();// 一直執(zhí)行
同時更新PrintWordsJob.java文件中的代碼為以下內(nèi)容:
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
?
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
?
public class PrintWordsJob implements Job {
??? @Override
??? public void execute(JobExecutionContext jobExecutionContext) {
??????? String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss:SSS").format(new Date());
??????? System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));
??????? JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
??????? System.out.println(jobDataMap.get("name").toString() + ":" + jobDataMap.get("age").toString() +":"+ jobDataMap.get("sex").toString());
??? }
}
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-22 01-00-24:165, prints: Hello scheduler
PrintWordsJob start at:23-08-22 01-00-24:176, prints: Hello Job-6
傳參test:11:男
PrintWordsJob start at:23-08-22 01-00-25:114, prints: Hello Job-70
傳參test:11:男
PrintWordsJob start at:23-08-22 01-00-26:106, prints: Hello Job-54
傳參test:11:男
…
…
…
PrintWordsJob start at:23-08-22 01-00-36:104, prints: Hello Job-73
傳參test:11:男
at:23-08-22 01-00-36:181, prints: Hello scheduler
--------scheduler shutdown ! ------------
十、任務(wù)操作
刪除
將下述藍(lán)色代碼取代上述【Quartz的簡單使用】TimeUnit.MILLISECONDS.sleep(12000);
這里休眠6秒后再執(zhí)行刪除job,運(yùn)行當(dāng)前刪除方法可以看到6秒后直接job方法不再執(zhí)行
// 睡眠6秒
TimeUnit.MILLISECONDS.sleep(6000);
// 刪除
scheduler.deleteJob(JobKey.jobKey("job1","group1"));
// 睡眠6秒
TimeUnit.MILLISECONDS.sleep(6000);
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-23 00-23-17:971, prints: Hello scheduler
PrintWordsJob start at:23-08-23 00-23-17:976, prints: Hello Job-13
PrintWordsJob start at:23-08-23 00-23-18:898, prints: Hello Job-1
PrintWordsJob start at:23-08-23 00-23-19:907, prints: Hello Job-89
PrintWordsJob start at:23-08-23 00-23-20:901, prints: Hello Job-17
PrintWordsJob start at:23-08-23 00-23-21:904, prints: Hello Job-74
PrintWordsJob start at:23-08-23 00-23-22:909, prints: Hello Job-70
PrintWordsJob start at:23-08-23 00-23-23:899, prints: Hello Job-42
at:23-08-23 00-23-29:990, prints: Hello scheduler
--------scheduler shutdown ! ------------
暫停、恢復(fù)
將下述藍(lán)色代碼取代上述【Quartz的簡單使用】TimeUnit.MILLISECONDS.sleep(12000);
這里先暫停job,休眠6秒后再恢復(fù)job,運(yùn)行程序可以看到6秒后先執(zhí)行job方法6次后,正常時間間隔執(zhí)行。
// 暫停
scheduler.pauseJob(JobKey.jobKey("job1","group1"));
// 睡眠6秒
TimeUnit.MILLISECONDS.sleep(6000);
// 恢復(fù)
scheduler.resumeJob(JobKey.jobKey("job1","group1"));
// 睡眠6秒
TimeUnit.MILLISECONDS.sleep(6000);
運(yùn)行結(jié)果(注意看時間):
--------scheduler start ! ------------
at:23-08-23 00-26-55:737, prints: Hello scheduler
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-82
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-97
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-27
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-39
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-88
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-87
PrintWordsJob start at:23-08-23 00-27-01:747, prints: Hello Job-58
PrintWordsJob start at:23-08-23 00-27-02:666, prints: Hello Job-76
PrintWordsJob start at:23-08-23 00-27-03:670, prints: Hello Job-78
PrintWordsJob start at:23-08-23 00-27-04:678, prints: Hello Job-79
PrintWordsJob start at:23-08-23 00-27-05:667, prints: Hello Job-63
PrintWordsJob start at:23-08-23 00-27-06:676, prints: Hello Job-93
PrintWordsJob start at:23-08-23 00-27-07:667, prints: Hello Job-90
at:23-08-23 00-27-07:745, prints: Hello scheduler
--------scheduler shutdown ! ------------
參考資料:
1. https://blog.csdn.net/faramita_of_mine/article/details/123142384?ops_request_misc=&request_id=&biz_id=102&utm_term=quartz&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-6-123142384.142^v93^chatgptT3_2&spm=1018.2226.3001.4187
2. https://blog.csdn.net/yoonbongchi/article/details/110579024?ops_request_misc=&request_id=&biz_id=102&utm_term=quartz&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-3-110579024.142^v93^chatgptT3_2&spm=1018.2226.3001.4187
3. https://blog.csdn.net/m0_47010003/article/details/124709983?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169244769016800227480253%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169244769016800227480253&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-124709983-null-null.142^v93^chatgptT3_2&utm_term=quartz&spm=1018.2226.3001.4187