这是我参与新手入门的第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就写好了。
更详细深刻的内容在后续文章中~