搜尋
首頁Javajava教程Quartz可以用來做什麼?

Quartz可以用來做什麼?

May 22, 2018 am 09:28 AM
quartz

Quartz可以用來做什麼?

Quartz是一個任務調度框架。例如你遇到這樣的問題

  • 想每月25號,信用卡自動還款

  • 想每年4月1日自己給當年暗戀女神發一封匿名賀卡

  • 想每隔1小時,備份一下自己的愛情動作片學習筆記到雲盤

這些問題總結起來就是:在某一個規律的時間點做某件事。而時間的觸發的條件可以非常複雜(例如每月最後一個工作日的17:50),複雜到需要一個專門的框架來幹這個事。 Quartz就是來做這樣的事,你給它一個觸發條件的定義,它負責到了時間點,觸發對應的Job起來工作。

廢話不多說,程式碼槓槓的。 。 。

public static void main(String[] args) {     
try { 
//创建scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//定义一个Trigger
Trigger trigger =TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") //定义name/group.startNow()//一旦加入scheduler,立即生效.
withSchedule(SimpleScheduleBuilder.simpleSchedule() //使用SimpleTrigger.withIntervalInSeconds(1) //每隔一秒执行一次.repeatForever()) //一直执行        
.build();
//定义一个JobDetail
JobDetail job =JobBuilder.newJob(HelloQuartz.class) //定义Job类为HelloQuartz类,这是真正的执行逻辑所在.withIdentity("job1", "group1") //定义name/group.usingJobData("name", "quartz") //定义属性        .build();
//加入这个调度    
scheduler.scheduleJob(job, trigger);
//启动之    
scheduler.start();
//运行一段时间后关闭 
Thread.sleep(10000);
      scheduler.shutdown(true);
   } catch (Exception e) {
    e.printStackTrace();
}

}

HelloQuartz类

public class HelloQuartz implements Job {public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDetail detail = context.getJobDetail();
        String name = detail.getJobDataMap().getString("name");
        System.out.println("say hello to " + name + " at " + new Date());
    }
}

jar套件:

這個例子很好的覆蓋了Quartz最重要的3個基本要素:

  • Scheduler:調度器。所有的調度都是由它來控制。

  • Trigger: 定義觸發的條件。例子中,它的類型是SimpleTrigger,每隔1秒中執行一次(什麼是SimpleTrigger下面會有詳述)。

  • JobDetail & Job: JobDetail 定義的是任務數據,而真正的執行邏輯是在Job中,範例中是HelloQuartz。 為什麼要設計成JobDetail + Job,不直接使用Job?這是因為任務是有可能並發執行,如果Scheduler直接使用Job,就會存在對同一個Job實例並發存取的問題。而JobDetail & Job 方式,sheduler每次執行,都會根據JobDetail建立一個新的Job實例,這樣就可以規避並發存取的問題。

Scheduler

Scheduler就是Quartz的大腦,所有任務都是由它來設施。

Schduelr包含一個兩個重要元件: JobStore和ThreadPool。

JobStore是會來儲存執行時間資訊的,包括Trigger,Schduler,JobDetail,業務鎖等。它有多種實作RAMJob(記憶體實作),JobStoreTX(JDBC,交易由Quartz管理),JobStoreCMT(JDBC,使用容器事務),ClusteredJobStore(叢集實作)、TerracottaJobStore(什麼是Terractta )

ThreadPool就是執行緒池,Quartz有自己的執行緒池實作。所有任務的都會由執行緒池執行。

SchedulerFactory

SchdulerFactory,顧名思義就是來用創建Schduler了,有兩個實作:DirectSchedulerFactory和 StdSchdulerFactory。前者可以用來在程式碼裡自訂自己的Schduler參數。後者是直接讀取classpath下的quartz.properties(不存在就都使用預設值)配置來實例化Schduler。通常來講,我們使用StdSchdulerFactory也就夠了。

SchdulerFactory本身是支援創建RMI stub的,可以用來管理遠端的Scheduler,功能與本地一樣,可以遠端提交個Job什麼的。

1.job

實作類別JobDetail

    JobDetail job = JobBuilder.newJob(RemindJob.class)
            .withIdentity("job1", "group1").build();//创建一个任务
     /**
      * 创建触发器
      * 第一种方式  不太好      */SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup").
    withSchedule(SimpleScheduleBuilder.simpleSchedule().
            withIntervalInSeconds(3).
            repeatForever()).
            startAt(new Date(System.currentTimeMillis()+1000)).build();    
    /**
     * 创建触发器
     * 第二种 方式  非常好
     * 可以 好用  2013年每月的第三个星期五上午10:30触发  0 30 10 ? * 6#3 2013
     * 2016年每月的第一个星期四下午16:17触发   0 17 16 ? * 5#1 2016
     * 每天15点到16点每5分钟运行一次,此外,每天17点到18点每5分钟运行一次  

     *//*CronTrigger trigger=TriggerBuilder.newTrigger() 
            .withIdentity("myTrigger", "myTriggerGroup")
            .withSchedule(CronScheduleBuilder.cronSchedule("0 18 16 ? * 5#1 2016")).build();*/
    SchedulerFactory sf=new StdSchedulerFactory();//创建调度者工厂Scheduler scheduler = sf.getScheduler();//创建一个调度者scheduler.scheduleJob(job,trigger);//注册并进行调度scheduler.start();//启动调度    //Thread.sleep(millis)    //scheduler.shutdown();//关闭调度

RemindJob 类的定义

#
 */public class RemindJob implements Job {private RemindService service=new RemindService();
    @Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        
        Date date=new Date();
        String time = date.toString();
        System.out.println(time+"job is starting");
    }

可以看到,我們傳給scheduler一個JobDetail實例,因為我們在建立JobDetail時,將要執行的job的類別名稱傳給了JobDetail,所以scheduler就知道了要執行何種類型的job;每次當scheduler執行job時,在呼叫其execute(…)方法之前會建立該類別的一個新的實例;執行完畢,對該實例的引用就被丟棄了,實例會被垃圾回收;這種執行策略帶來的一個後果是,job必須有一個無參的建構子(當使用預設的JobFactory);另一個後果是,在job類別中,不應該定義有狀態的資料屬性,因為在job的多次執行中,這些屬性的值不會保留。

那麼如何為job實例增加屬性或配置呢?如何在job的多次執行中,追蹤job的狀態?答案就是:JobDataMap,JobDetail物件的一部分。

JobDataMap

JobDataMap中可以包含不限量的(序列化的)資料對象,在job實例執行的時候,可以使用其中的資料;JobDataMap是Java Map介面的一個實現,額外增加了一些便於存取基本類型的資料的方法。

將job加入scheduler之前,在建構JobDetail時,可以將資料放入JobDataMap,如下範例:

    JobDetail job=JobBuilder.newJob(RemindJob.class)
            .withIdentity("job1", "group1")
            .usingJobData("hello", "we are family")
            .build();

在job的執行過程中,可以從JobDataMap中取出數據,如下範例:

@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        JobKey key=context.getJobDetail().getKey();
        
        JobDataMap map = context.getJobDetail().getJobDataMap();
        String string = map.getString("hello");
        System.out.println(key+"==========="+string);
        
        Date date=new Date();
        String time = date.toString();
        System.out.println(time+"job is starting");
    }

如果你使用的是持久化的存储机制(本教程的JobStore部分会讲到),在决定JobDataMap中存放什么数据的时候需要小心,因为JobDataMap中存储的对象都会被序列化,因此很可能会导致类的版本不一致的问题;Java的标准类型都很安全,如果你已经有了一个类的序列化后的实例,某个时候,别人修改了该类的定义,此时你需要确保对类的修改没有破坏兼容性;更多细节,参考现实中的序列化问题。另外,你也可以配置JDBC-JobStore和JobDataMap,使得map中仅允许存储基本类型和String类型的数据,这样可以避免后续的序列化问题。

如果你在job类中,为JobDataMap中存储的数据的key增加set方法(如在上面示例中,增加setJobSays(String val)方法),那么Quartz的默认JobFactory实现在job被实例化的时候会自动调用这些set方法,这样你就不需要在execute()方法中显式地从map中取数据了。

在Job执行时,JobExecutionContext中的JobDataMap为我们提供了很多的便利。它是JobDetail中的JobDataMap和Trigger中的JobDataMap的并集,但是如果存在相同的数据,则后者会覆盖前者的值。

下面的示例,在job执行时,从JobExecutionContext中获取合并后的JobDataMap:

@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        JobKey key=context.getJobDetail().getKey();        /*    JobDataMap map = context.getJobDetail().getJobDataMap();
        String string = map.getString("hello");
        System.out.println(key+"==========="+string);*/ JobDataMap map = context.getMergedJobDataMap();
         String string = map.getString("hello");
         System.out.println(key+"---------------------    "+string);

 

以上是Quartz可以用來做什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)