欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解定時(shí)任務(wù)框架Quartz的使用

 更新時(shí)間:2023年02月13日 10:19:00   作者:山西彭于晏  
Quartz是OpenSymphony開源組織在Job?scheduling領(lǐng)域又一個(gè)開源項(xiàng)目,完全由Java開發(fā),可以用來執(zhí)行定時(shí)任務(wù),本文就來帶大家聊聊它的具體使用

一、什么是Quartz

什么是Quartz?

Quartz是OpenSymphony開源組織在Job scheduling領(lǐng)域又一個(gè)開源項(xiàng)目,完全由Java開發(fā),可以用來執(zhí)行定時(shí)任務(wù),類似于java.util.Timer。但是相較于Timer, Quartz增加了很多功能:

  • 持久性作業(yè) – 就是保持調(diào)度定時(shí)的狀態(tài);
  • 作業(yè)管理 – 對調(diào)度作業(yè)進(jìn)行有效的管理;

大部分公司都會用到定時(shí)任務(wù)這個(gè)功能。 拿火車票購票來說,當(dāng)你下單后,后臺就會插入一條待支付的task(job),一般是30分鐘,超過30min后就會執(zhí)行這個(gè)job,去判斷你是否支付,未支付就會取消此次訂單;當(dāng)你支付完成之后,后臺拿到支付回調(diào)后就會再插入一條待消費(fèi)的task(job),Job觸發(fā)日期為火車票上的出發(fā)日期,超過這個(gè)時(shí)間就會執(zhí)行這個(gè)job,判斷是否使用等。

在我們實(shí)際的項(xiàng)目中,當(dāng)Job過多的時(shí)候,肯定不能人工去操作,這時(shí)候就需要一個(gè)任務(wù)調(diào)度框架,幫我們自動去執(zhí)行這些程序。那么該如何實(shí)現(xiàn)這個(gè)功能呢?

(1)首先我們需要定義實(shí)現(xiàn)一個(gè)定時(shí)功能的接口,我們可以稱之為Task(或Job),如定時(shí)發(fā)送郵件的task(Job),重啟機(jī)器的task(Job),優(yōu)惠券到期發(fā)送短信提醒的task(Job),實(shí)現(xiàn)接口如下:

(2)有了任務(wù)之后,還需要一個(gè)能夠?qū)崿F(xiàn)觸發(fā)任務(wù)去執(zhí)行的觸發(fā)器,觸發(fā)器Trigger最基本的功能是指定Job的執(zhí)行時(shí)間,執(zhí)行間隔,運(yùn)行次數(shù)等。

(3)有了Job和Trigger后,怎么樣將兩者結(jié)合起來呢?即怎樣指定Trigger去執(zhí)行指定的Job呢?這時(shí)需要一個(gè)Schedule,來負(fù)責(zé)這個(gè)功能的實(shí)現(xiàn)。

上面三個(gè)部分就是Quartz的基本組成部分:

  • 調(diào)度器:Scheduler
  • 任務(wù):JobDetail
  • 觸發(fā)器:Trigger,包括SimpleTrigger和CronTrigger

二、Quartz Demo搭建

下面來利用Quartz搭建一個(gè)最基本的Demo。

1、導(dǎo)入依賴的jar包:

org.quartz-scheduler quartz 2.3.0

2、新建一個(gè)能夠打印任意內(nèi)容的Job:

/** * Created by wanggenshen * Date: on 2018/7/7 16:28. * Description: 打印任意內(nèi)容 */
public class PrintWordsJob implements Job{ 


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));

    }
}

3、創(chuàng)建Schedule,執(zhí)行任務(wù):

/** * Created by wanggenshen * Date: on 2018/7/7 16:31. * Description: XXX */
public class MyScheduler { 


    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1、創(chuàng)建調(diào)度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 2、創(chuàng)建JobDetail實(shí)例,并與PrintWordsJob類綁定(Job執(zhí)行內(nèi)容)
        JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
                                        .withIdentity("job1", "group1").build();
        // 3、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
                .startNow()//立即生效
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1)//每隔1s執(zhí)行一次
                .repeatForever()).build();//一直執(zhí)行

        //4、執(zhí)行
        scheduler.scheduleJob(jobDetail, trigger);
        System.out.println("--------scheduler start ! ------------");
        scheduler.start();

        //睡眠
        TimeUnit.MINUTES.sleep(1);
        scheduler.shutdown();
        System.out.println("--------scheduler shutdown ! ------------");


    }
}

運(yùn)行程序,可以看到程序每隔1s會打印出內(nèi)容,且在一分鐘后結(jié)束:

三、Quartz核心詳解

下面就程序中出現(xiàn)的幾個(gè)參數(shù),看一下Quartz框架中的幾個(gè)重要參數(shù):

  • Job和JobDetail
  • JobExecutionContext
  • JobDataMap
  • Trigger、SimpleTrigger、CronTrigger

(1)Job和JobDetail Job是Quartz中的一個(gè)接口,接口下只有execute方法,在這個(gè)方法中編寫業(yè)務(wù)邏輯。 接口中的源碼:

JobDetail用來綁定Job,為Job實(shí)例提供許多屬性:

  • name
  • group
  • jobClass
  • jobDataMap

JobDetail綁定指定的Job,每次Scheduler調(diào)度執(zhí)行一個(gè)Job的時(shí)候,首先會拿到對應(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,就會存在對同一個(gè)Job實(shí)例并發(fā)訪問的問題。而JobDetail & Job 方式,Sheduler每次執(zhí)行,都會根據(jù)JobDetail創(chuàng)建一個(gè)新的Job實(shí)例,這樣就可以規(guī)避并發(fā)訪問的問題。

(2)JobExecutionContext

JobExecutionContext中包含了Quartz運(yùn)行時(shí)的環(huán)境以及Job本身的詳細(xì)數(shù)據(jù)信息。 當(dāng)Schedule調(diào)度執(zhí)行一個(gè)Job的時(shí)候,就會將JobExecutionContext傳遞給該Job的execute()中,Job就可以通過JobExecutionContext對象獲取信息。 主要信息有:

(3)JobExecutionContext JobDataMap實(shí)現(xiàn)了JDK的Map接口,可以以Key-Value的形式存儲數(shù)據(jù)。 JobDetail、Trigger都可以使用JobDataMap來設(shè)置一些參數(shù)或信息, Job執(zhí)行execute()方法的時(shí)候,JobExecutionContext可以獲取到JobExecutionContext中的信息: 如:

JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)                        .usingJobData("jobDetail1", "這個(gè)Job用來測試的")
                  .withIdentity("job1", "group1").build();

 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
      .usingJobData("trigger1", "這是jobDetail1的trigger")
      .startNow()//立即生效
      .withSchedule(SimpleScheduleBuilder.simpleSchedule()
      .withIntervalInSeconds(1)//每隔1s執(zhí)行一次
      .repeatForever()).build();//一直執(zhí)行

Job執(zhí)行的時(shí)候,可以獲取到這些參數(shù)信息:

 @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetail1"));
        System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("trigger1"));
        String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
        System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-" + new Random().nextInt(100));


    }

(4)Trigger、SimpleTrigger、CronTrigger

Trigger

Trigger是Quartz的觸發(fā)器,會去通知Scheduler何時(shí)去執(zhí)行對應(yīng)Job。

  • new Trigger().startAt():表示觸發(fā)器首次被觸發(fā)的時(shí)間;
  • new Trigger().endAt():表示觸發(fā)器結(jié)束觸發(fā)的時(shí)間;

SimpleTrigger

SimpleTrigger可以實(shí)現(xiàn)在一個(gè)指定時(shí)間段內(nèi)執(zhí)行一次作業(yè)任務(wù)或一個(gè)時(shí)間段內(nèi)多次執(zhí)行作業(yè)任務(wù)。 下面的程序就實(shí)現(xiàn)了程序運(yùn)行5s后開始執(zhí)行Job,執(zhí)行Job 5s后結(jié)束執(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í)行

CronTrigger

CronTrigger功能非常強(qiáng)大,是基于日歷的作業(yè)調(diào)度,而SimpleTrigger是精準(zhǔn)指定間隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表達(dá)式的,先了解下Cron表達(dá)式: 由7個(gè)子表達(dá)式組成字符串的,格式如下:

[秒] [分] [小時(shí)] [日] [月] [周] [年]

Cron表達(dá)式的語法比較復(fù)雜, 如:* 30 10 ? * 1/5 * 表示(從后往前看) [指定年份] 的[ 周一到周五][指定月][不指定日][上午10時(shí)][30分][指定秒]

又如:00 00 00 ? * 10,11,12 1#5 2018 表示2018年10、11、12月的第一周的星期五這一天的0時(shí)0分0秒去執(zhí)行任務(wù)。

下面是給的一個(gè)例子:

可通過在線生成Cron表達(dá)式的工具:cron.qqe2.com/ 來生成自己想要的表達(dá)式。

下面的代碼就實(shí)現(xiàn)了每周一到周五上午10:30執(zhí)行定時(shí)任務(wù)

/** * Created by wanggenshen * Date: on 2018/7/7 20:06. * Description: XXX */
public class MyScheduler2 { 

    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1、創(chuàng)建調(diào)度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 2、創(chuàng)建JobDetail實(shí)例,并與PrintWordsJob類綁定(Job執(zhí)行內(nèi)容)
        JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
                .usingJobData("jobDetail1", "這個(gè)Job用來測試的")
                .withIdentity("job1", "group1").build();
        // 3、構(gòu)建Trigger實(shí)例,每隔1s執(zhí)行一次
        Date startDate = new Date();
        startDate.setTime(startDate.getTime() + 5000);

        Date endDate = new Date();
        endDate.setTime(startDate.getTime() + 5000);

        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
                .usingJobData("trigger1", "這是jobDetail1的trigger")
                .startNow()//立即生效
                .startAt(startDate)
                .endAt(endDate)
                .withSchedule(CronScheduleBuilder.cronSchedule("* 30 10 ? * 1/5 2018"))
                .build();

        //4、執(zhí)行
        scheduler.scheduleJob(jobDetail, cronTrigger);
        System.out.println("--------scheduler start ! ------------");
        scheduler.start();
        System.out.println("--------scheduler shutdown ! ------------");

    }
}

到此這篇關(guān)于詳解定時(shí)任務(wù)框架Quartz的使用的文章就介紹到這了,更多相關(guān)定時(shí)任務(wù)框架Quartz內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot常用注解及配置文件加載順序詳解

    Springboot常用注解及配置文件加載順序詳解

    這篇文章主要介紹了Springboot常用注解及配置文件加載順序,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • java ArrayList中的remove方法介紹

    java ArrayList中的remove方法介紹

    大家好,本篇文章主要講的是java ArrayList中的remove方法介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • java文件讀寫工具類分享

    java文件讀寫工具類分享

    這篇文章主要為大家詳細(xì)介紹了java文件讀寫工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 新手了解java 異常處理基礎(chǔ)知識

    新手了解java 異常處理基礎(chǔ)知識

    Java中異常提供了一種識別及響應(yīng)錯誤情況的一致性機(jī)制,有效地異常處理能使程序更加健壯、易于調(diào)試。那么這篇文章總結(jié)了Java有效處理異常的三個(gè)原則,有需要的朋友們可以參考借鑒
    2021-07-07
  • InputStream數(shù)據(jù)結(jié)構(gòu)示例解析

    InputStream數(shù)據(jù)結(jié)構(gòu)示例解析

    這篇文章主要為大家介紹了InputStream數(shù)據(jù)結(jié)構(gòu)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Java8不可或缺小幫手之日期應(yīng)用

    Java8不可或缺小幫手之日期應(yīng)用

    jdk1.8后引入了新的日期時(shí)間處理API,相比傳統(tǒng)的date操作更加簡便,date中的SimpleDateFormat也是非線程安全的,廢話不多說,開干
    2023-05-05
  • Java排序算法中的選擇排序算法實(shí)現(xiàn)

    Java排序算法中的選擇排序算法實(shí)現(xiàn)

    這篇文章主要介紹了Java排序算法中的選擇排序算法實(shí)現(xiàn),選擇排序算法的實(shí)現(xiàn)思路類似插入排序,分已排序區(qū)間和未排序區(qū)間,選擇排序每次會從未排序區(qū)間中找到最小(大)的元素,將其放到已排序區(qū)間的末尾,需要的朋友可以參考下
    2023-12-12
  • 詳解如何將JAR包發(fā)布到Maven中央倉庫

    詳解如何將JAR包發(fā)布到Maven中央倉庫

    這篇文章主要介紹了詳解如何將JAR包發(fā)布到Maven中央倉庫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Spring 4.0新功能:@Conditional注解詳細(xì)介紹

    Spring 4.0新功能:@Conditional注解詳細(xì)介紹

    Spring Boot的強(qiáng)大之處在于使用了Spring 4框架的新特性:@Conditional注釋,此注釋使得只有在特定條件滿足時(shí)才啟用一些配置。下面這篇文章主要給大家介紹了關(guān)于Spring4.0中新功能:@Conditional注解的相關(guān)資料,需要的朋友可以參考下。
    2017-09-09
  • 通過簡單步驟實(shí)現(xiàn)SpringMVC文件上傳

    通過簡單步驟實(shí)現(xiàn)SpringMVC文件上傳

    這篇文章主要介紹了通過簡單步驟實(shí)現(xiàn)SpringMVC文件上傳,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評論