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就写好了。

更详细深刻的内容在后续文章中~

相关文章
相关标签/搜索