Quartz -----定時任務框架


一.什么是Quartz
 
 
由java開發用來執行定時任務,類似於java.util.Timer.   但是相較於Timer,quartz增加了很多功能:
        
        持久性作業-就是保持調度定時的狀態
 
        作業管理-對調度作業進行有效的管理
 
 
(1)首先我們需要定義實現一個定時功能的接口,稱之為Task(或Job),如定時發送郵件的task(Job),重啟機器的task(Job),優惠券到期發送短信提醒的task(Job),實現接口如下:
                     

(2)有了任務后,還需要一個能夠實現觸發任務去執行的觸發器,觸發器Traigger最基本的功能是指定job的執行時間,執行間隔,運行次數等

               

 

(3)有了job和trigger后,怎么樣將兩者結合起來,即怎樣指定Trigger去執行指定的job?這就需要一個schedule,來負責這個功能的實現
      

        

上面三個部分就是quartz的基本組成部分:
 
            1. 調度器: Scheduler
            2. 任務:    JobDetail
            3. 觸發器:Trigger    包括SimpleTrigger和CroTrigger
 
 

二、Quartz Demo搭建

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

1、導入依賴的jar包:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

 

2.配置信息

# 名為:quartz.properties,放置在classpath下,如果沒有此配置則按默認配置啟動
# 指定調度器名稱,非實現類
org.quartz.scheduler.instanceName = DefaultQuartzScheduler04
# 指定線程池實現類
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 線程池線程數量
org.quartz.threadPool.threadCount = 10 
# 優先級,默認5
org.quartz.threadPool.threadPriority = 5
# 非持久化job
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

 

3、新建一個能夠打印任意內容的Job:

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));

    }
}

 

4、創建Schedule,執行任務:

public class MyScheduler {

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

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

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

    }
}

 

運行程序,可以看到程序每隔1s會打印出內容,且在一分鍾后結束:

 

三、Quartz核心詳解

下面就程序中出現的幾個參數,看一下Quartz框架中的幾個重要參數:

  • Job和JobDetail
  • JobExecutionContext
  • JobDataMap
  • Trigger、SimpleTrigger、CronTrigger
1,JobDetail用來綁定job,為job實例提供許多屬性:
        . name
        . group
        . jobclass
        . jobDataMap
  jobDetail綁定指定的job,每次Scheduler調度執行一個job時,首先會拿到對印的job,然后先創建該job實例,再去執行再去執行job中的execute()的內容,任務執行結束后,關聯的job對象實例會被釋放,且會被jvm GC清除
 
  jobDetail定義的是任務數據,而真正的執行邏輯實在job中。
  這是應為任務時有可能並發執行的,如果Scheduler直接使用job,就會存在對同一個job實例並發訪問的問題, 而JobDetail & Job 方式,Sheduler每次執行,都會根據JobDetail創建一個新的Job實例,這樣就可以規避並發訪問的問題。

 

2.JobExecutionContext
  JobExecutionContext中包含了Quartz運行時的環境以及Job本身的詳細數據信息。
當Schedule調度執行一個Job的時候,就會將JobExecutionContext傳遞給該Job的execute()中,Job就可以通過JobExecutionContext對象獲取信息。

 

                               

3.JobDataMap

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

4.Trigger、SimpleTrigger、CronTrigger

 

    (1).trigger是Quartz的觸發器,會去通知Scheduler何時去執行對應job
 
             new Trigger().startAt():表示觸發器首次被觸發的時間; 
             new Trigger().endAt():表示觸發器結束觸發的時間;
 
 
    (2)  SimpleTrigger:  可以實現在一個時間段內執行一次作業任務或一個時間段內多次執行作業任務。
 
 
    (3) CronTrigger:CroTrigger功能非常強大,是基於日歷的作業調度,而SimpleTrigger是精准指定間隔,所以相比SimpleTrigger,CronTrigger更加常用。CroTrigger是基於Cron表達式的,cron表達式格式如下: 
                              
  [秒] [分] [小時] [日] [月] [周] [年]

 

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

 

 

下面的代碼就實現了每周一到周五上午15:00執行定時任務

 

public class MyScheduler2 {

    public static void main(String[] args) throws SchedulerException {
        //創建調度器Scheduler
        SchedulerFactory schedulerFactory=new StdSchedulerFactory();
        Scheduler scheduler=schedulerFactory.getScheduler();
        //創建jobDetail實例,並與printWordsJob類綁定(job執行內容)
        JobDetail jobDetail= JobBuilder.newJob(PrintWordsJob.class).usingJobData("jobDetail1","這個job用來測試的")
                .withIdentity("job1","group1").build();
        //構建Trigger實例,每隔一秒執行一次
        //實現程序運行5s后開始執行Job,執行Job 5s后結束執行:
        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("* 00 15 ? * 1/5 2019")).build();

        scheduler.scheduleJob(jobDetail,cronTrigger);
        System.out.println("--------scheduler start ! ------------");
        scheduler.start();
        System.out.println("--------scheduler shutdown ! ------------");


    }
}

原文鏈接:https://blog.csdn.net/noaman_wgs/article/details/80984873

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM