Java定時任務調度(2)Quart框架的簡單介紹

這是我參與新手入門的第2篇文章。html

1、前言

在以前的文章《Java定時任務調度(1)TimerTask原理與實戰》中已經介紹了一種實現定時任務調度的方法——Java原生提供的 TimerTask,這個工具適用於一些簡單的業務需求。java

回顧一下,TimerTask的原理總結起來就是下面這個圖:spring

image.png

其實仔細想一想,是否是能夠抽象出來幾個部分?markdown

任務調度,首先要有任務,TimerTask就是 具體任務。有了任務以後是否是要給這個任務設置一下啥時候調,多久調一次,啥時候終止啊?這一步能夠叫作 條件設置。那麼剩下的就是具體執行,能夠叫作 執行器app

image.png

其實就具體代碼上來講,後兩個都是調Timer的方法框架

Timer timer = new Timer();
    long delay = 0;
    long period = 1000;
    timer.schedule(timerTask, delay, period);
複製代碼

可是,Timer存在一個嚴重的問題,它是 單線程 的。ide

若是你有多個任務,且第一個任務執行時間超過了兩個任務的間隔時間,那麼第二個任務就不能按時執行,此時能夠選擇使用ScheduledExecutorService來解決,它的內部是個線程池,此外它也能解決上篇文章中提到的Timer異常退出問題。svn

2、Quartz的簡單介紹

那麼接下來,就按照這個思路來介紹一個更強大的Java任務調度框架——Quartz工具

Quartz有一個官方版的簡單介紹:oop

Quartz 容許開發人員根據時間間隔(或天)來調度做業。它實現了做業和觸發器的多對多關係,還能把多個做業與不一樣的觸發器關聯。整合了 Quartz 的應用程序能夠重用來自不一樣事件的做業,還能夠爲一個事件組合多個做業。

 若是歷來沒有接觸過任務調度的東西,光看這確定也懵,不過相信你看徹底篇再回過頭來,就明白了。

說來也巧,Quartz的設計思路就是上面總結的三部分,只不過名字不一樣。

  • Job:具體要執行的任務邏輯

  • Trigger:觸發器,設置Job的觸發條件、間隔,終止時間

  • Scheduler:調度器,啓動Trigger執行Job

這麼看是否是和前言中對TimerTask的總結一致了?

Quartz Demo的建立

若是使用傳統方式,就是去官方下載一個jar包,新建一個Java project,導包就能夠了。 如今通常都是使用自動化構建工具了。

打開start.spring.io/ 填寫相關配置,這裏我使用Maven

image.png

固然此處也能夠選擇右側的add dependencies,那我通常都是本身在pom文件中添加依賴。

導入依賴

<dependency>
	    <groupId>org.quartz-scheduler</groupId>
	    <artifactId>quartz</artifactId>
	    <version>2.3.2</version>
	</dependency>
複製代碼

寫Demo

public static void main(String[] args) {
		 try {
             // 工廠方法獲取默認的調度器
             Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

             // 啓動
             scheduler.start();
             //關閉
             scheduler.shutdown();

         } catch (SchedulerException se) {
             se.printStackTrace();
         }
	}
複製代碼

其實這個例子是官網提供的【www.quartz-scheduler.org/documentati… 很簡單,一共就三行代碼。

執行結果是什麼那?

22:47:27.348 [main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
22:47:27.355 [main] INFO org.quartz.simpl.SimpleThreadPool - Job execution threads will use class loader of thread: main 22:47:27.370 [main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 22:47:27.370 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.2 created. 22:47:27.371 [main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized. 22:47:27.372 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.2) '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. 22:47:27.372 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 22:47:27.372 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.2 22:47:27.372 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. 22:47:27.372 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down. 22:47:27.372 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused. 22:47:27.372 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutting down threadpool... 22:47:27.372 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 0 triggers 22:47:27.372 [main] DEBUG org.quartz.simpl.SimpleThreadPool - Shutdown of threadpool complete. 22:47:27.372 [main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete. 22:47:27.868 [DefaultQuartzScheduler_Worker-6] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-10] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-5] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-4] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-3] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.869 [DefaultQuartzScheduler_Worker-2] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.869 [DefaultQuartzScheduler_Worker-1] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-7] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-8] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 22:47:27.868 [DefaultQuartzScheduler_Worker-9] DEBUG org.quartz.simpl.SimpleThreadPool - WorkerThread is shut down. 複製代碼

輸出的結果仍是有不少看頭的

Quartz Scheduler v.2.3.2 created  能夠看到使用版本
RAMJobStore initialized  能夠看到存儲方式是RAMJobStore
最後面的SimpleThreadPool 就是線程池,一共有1-10   10個線程
複製代碼

看到線程池,你會想到什麼?

能夠參考個人上篇文章:《Java定時任務調度(1)TimerTask原理與實戰》

假如我把第三行代碼註釋掉,會發生什麼? 注意箭頭的位置,這個程序並無中止。

image.png 這裏官網也有解釋:

Once you obtain a scheduler using StdSchedulerFactory.getDefaultScheduler(), your application will not terminate until you call scheduler.shutdown(), because there will be active threads.

一旦使用StdSchedulerFactory.getDefaultScheduler()得到調度程序,在調用scheduler.shutdown()以前,應用程序不會終止,由於會有活動線程。

有了啓動和中止,任務的具體執行天然就在這中間來完成。

image.png

把官網的例子複製過來,很明顯,出現了錯誤。 具體緣由就是一個是沒有HelloJob這個類,另外一個靜態導入要補上

public class HelloJob implements Job{

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		// TODO Auto-generated method stub
		
		SimpleDateFormat  simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		System.out.println("你好!當前時間是:"+simpleDateFormat.format(new Date()));
	}
	
}


//注意,靜態導入不在這個HelloJob類中

import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
複製代碼

固然在執行以前,必定要在中止的前面加上Thread.sleep(),要否則,直接就關閉了。

爲了儘快的看到效果,我把間隔時間設置爲5秒

效果:

image.png

好了,簡單的Demo就寫好了。

更詳細深刻的內容在後續文章中~

相關文章
相關標籤/搜索