這是我參與新手入門的第2篇文章。html
在以前的文章《Java定時任務調度(1)TimerTask原理與實戰》中已經介紹了一種實現定時任務調度的方法——Java原生提供的 TimerTask
,這個工具適用於一些簡單的業務需求。java
回顧一下,TimerTask的原理總結起來就是下面這個圖:spring
其實仔細想一想,是否是能夠抽象出來幾個部分?markdown
任務調度,首先要有任務,TimerTask就是 具體任務
。有了任務以後是否是要給這個任務設置一下啥時候調,多久調一次,啥時候終止啊?這一步能夠叫作 條件設置
。那麼剩下的就是具體執行,能夠叫作 執行器
。app
其實就具體代碼上來講,後兩個都是調Timer的方法框架
Timer timer = new Timer();
long delay = 0;
long period = 1000;
timer.schedule(timerTask, delay, period);
複製代碼
可是,Timer存在一個嚴重的問題,它是 單線程
的。ide
若是你有多個任務,且第一個任務執行時間超過了兩個任務的間隔時間,那麼第二個任務就不能按時執行,此時能夠選擇使用ScheduledExecutorService來解決,它的內部是個線程池,此外它也能解決上篇文章中提到的Timer異常退出問題。svn
那麼接下來,就按照這個思路來介紹一個更強大的Java任務調度框架——Quartz
工具
Quartz有一個官方版的簡單介紹:oop
Quartz 容許開發人員根據時間間隔(或天)來調度做業。它實現了做業和觸發器的多對多關係,還能把多個做業與不一樣的觸發器關聯。整合了 Quartz 的應用程序能夠重用來自不一樣事件的做業,還能夠爲一個事件組合多個做業。
若是歷來沒有接觸過任務調度的東西,光看這確定也懵,不過相信你看徹底篇再回過頭來,就明白了。
說來也巧,Quartz的設計思路就是上面總結的三部分,只不過名字不一樣。
Job:具體要執行的任務邏輯
Trigger:觸發器,設置Job的觸發條件、間隔,終止時間
Scheduler:調度器,啓動Trigger執行Job
這麼看是否是和前言中對TimerTask的總結一致了?
若是使用傳統方式,就是去官方下載一個jar包,新建一個Java project,導包就能夠了。 如今通常都是使用自動化構建工具了。
打開start.spring.io/ 填寫相關配置,這裏我使用Maven
固然此處也能夠選擇右側的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原理與實戰》
假如我把第三行代碼註釋掉,會發生什麼? 注意箭頭的位置,這個程序並無中止。
這裏官網也有解釋:
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()以前,應用程序不會終止,由於會有活動線程。
有了啓動和中止,任務的具體執行天然就在這中間來完成。
把官網的例子複製過來,很明顯,出現了錯誤。 具體緣由就是一個是沒有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秒
效果:
好了,簡單的Demo就寫好了。
更詳細深刻的內容在後續文章中~