学习使用Java Quartz任务调度(一)

学习使用Java Quartz任务调度(一)//本着以交流经验和学习的态度来分享知识,如果有误,请批评指出,不胜感激!现在企业中基本均有涉及到任务调度和异步执行器,在Java方向,提供了开源的Quartz、JDK提供了Timer。在以上基础前提下,Java5.0通过java.util.concurrent这个新包以及它下边的诸多类和接口,提供了方便的线程池调用。在本篇文章中,我们主要使用Quartz来作为解决任务调度的工具。为什么不…

大家好,又见面了,我是你们的朋友全栈君。

//本着以交流经验和学习的态度来分享知识,如果有误,请批评指出,不胜感激!

现在企业中基本均有涉及到任务调度和异步执行器,在Java方向,提供了开源的Quartz、JDK提供了Timer。在以上基础前提下,Java5.0通过java.util.concurrent这个新包以及它下边的诸多类和接口,提供了方便的线程池调用。

在本篇文章中,我们主要使用Quartz来作为解决任务调度的工具。为什么不是用JDK提供的方法?

//(因为Timer解决基础的调度室没有问题的,但是如果处理复杂逻辑调度和类似于每个星期一12:00处理任务,这种复杂时间,就有点捉急了)。

废话不多说,我们先做一个‘简单’的Quartz Demo来’简单’介绍一下Quartz的基本使用方法和功能

我先简单介绍一下Quartz的核心接口和类(如果已经了解的请略过):

1.Job,这是一个接口,并且只有一个void execute(JobExecutionContext context) throws JobExecutionException 的方法。这个方法定义了需要调度的方法,开发者在使用Quartz并定义调度任务时候,需要实现这个接口并且重写此方法。

2.JobDetail,看名字也知道这是Job的实现类,当Quartz执行Job时,它会接受JobDetail这个实现类,通过newInstance()的反射调用机制来实例化一个Job,也就是说,在实例化Job时,需要有一个返回值来接受实例化的Job和一些静态信息。

3.Trigger,这是一个类,包括两个子类,主要是触发Job执行的时间触发规则,主要有SimpleTrigger和CronTrigger两个子类;当仅需要触发一次或者以固定检核周期性执行时,SimpleTrigger一定是最合适的选择,当如果要执行复杂的调度规则时,则可以使用CronTrigger。

4.Scheduler,代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,二者在Scheduler中有各自的组件、名称和组

暂时需要了解到这4样核心API,说一说我的理解就是:当你创建一个Job和Trigger之后,将这两个放到Quartz容器 Scheduler中,通过启动Scheduler来启动Job

现在,我们创建一个工程来实际使用一下

学习使用Java Quartz任务调度(一)

这个是完成后的Demo所有文件

我们一步一步来,在Maven中首先引入依赖,如下图

    <dependency>
  		<groupId>org.quartz-scheduler</groupId>
  		<artifactId>quartz</artifactId>
  		<version>2.2.1</version>
  	</dependency>
  	<dependency>
  		<groupId>org.quartz-scheduler</groupId>
  		<artifactId>quartz-jobs</artifactId>
  		<version>2.2.1</version>
  	</dependency>
  	<dependency>
  		<groupId>org.slf4j</groupId>
  		<artifactId>slf4j-log4j12</artifactId>
  		<version>1.6.6</version>
  	</dependency>

然后创建一个针对RAM存储的JOB类,这个类是Job 的实现类,在实现Job接口后需要重写execute方法,在方法中定义需要执行的任务,举个例子如下

package quartz.demo;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RAMJob implements Job{

	private Logger log = LoggerFactory.getLogger(RAMJob.class);
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		
		log.info("我也不知道这个啥时候执行,反正这个是Job 的实现类");
	}

}

然后我们在创建一个类,用来执行一个简单的任务执行器,在新的类中我们使用main方法来启动执行,在执行之前,我们需要先定义一个JobDetail对象,如图:

//创建一个JobDetail
		JobDetail jobDetail = JobBuilder.newJob(RAMJob.class)
				.withDescription("调用JobDemo")
				.withIdentity("Job's name", "Job's Group")
				.build();
		log.info("描述任务:{}" + jobDetail.getDescription());

具体的任务描述和设置都已在方法中定义,不过想了解的盆友可以点开看看源码,都很简单,这里不再阐述。

在定义完Job后,我们需要再定义一个Trigger触发规则,如下:

        //创建一个trigger触发规则
		Trigger trigger = TriggerBuilder.newTrigger()
				.withDescription("创建一个Trigger触发规则")
				.startAt(new Date())
				.withIdentity("Trigger's Name", "Trigger's Group")
				.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(10,5))
				.build();

这里可能很多没看源码的人看不懂或者是别的情况,我简单解释一下各个方法的作用,我们通过TriggerBuilder新建一个TriggerBuilder对象,

.withDescription(String description);根据字面意思,这个方法表示针对这个Trigger进行描述;

.startAt(Date triggerStartTime):根据字面单词意思,这就是设置Trigger规则启动时间的方法;

.withIdentity();这个方法是设置Trigger基本信息的方法,通过源码我们可以看到有三个重载的方法,分别是:.withIdentity(String name);.withIdentity(String name , String group);.withIdentity(TriggerKey triggerKey),这三个方法的本身操作其实是无差别的,都是要给初始化给TriggerKey对象赋值;

在完成上面两个基本任务后,我们开始构建Quartz容器,要注意一点,Quartz容器(Scheduler)是独立运行的,Scheduler可以将Trigger绑定到某一个JobDetail上,当Trigger被触发时,对应的Job就被执行,一个Job可以对应多个Trigger,一个Trigger只能对应一个Job,我们一般通过SchedulerFactory创建一个Scheduler实例;如下图:

        //创建一个调度器,也就是一个Quartz容器
        //声明一个scheduler的工厂schedulerFactory
		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //通过schedulerFactory来实例化一个Scheduler
		Scheduler scheduler = schedulerFactory.getScheduler();
        //将Job和Trigger注册到scheduler容器中
		scheduler.scheduleJob(jobDetail,trigger);

最后,我们启动scheduler容器:

    //启动容器
    log.info("JOB开始启动);
    ​
    scheduler.start();

​

此时我们就完全启动了一个任务异步执行,启动日志如下:

10:22:35,093 [main] INFO  quartz.demo.SimpleTriggerTest  - Job开始执行
10:22:35,099 [main] INFO  quartz.demo.SimpleTriggerTest  - 描述任务:{}调用JobDemo
10:22:35,167 [main] INFO  com.mchange.v2.log.MLog  - MLog clients using log4j logging.
10:22:35,458 [main] INFO  com.mchange.v2.c3p0.C3P0Registry  - Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10]
10:22:35,482 [main] INFO  org.quartz.impl.StdSchedulerFactory  - Using default implementation for ThreadExecutor
10:22:35,494 [main] INFO  org.quartz.core.SchedulerSignalerImpl  - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
10:22:35,495 [main] INFO  org.quartz.core.QuartzScheduler  - Quartz Scheduler v.2.2.1 created.
10:22:35,496 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Using thread monitor-based data access locking (synchronization).
10:22:35,496 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - JobStoreTX initialized.
10:22:35,497 [main] INFO  org.quartz.core.QuartzScheduler  - Scheduler meta-data: Quartz Scheduler (v2.2.1) 'dufy_test' 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.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered.

10:22:35,497 [main] INFO  org.quartz.impl.StdSchedulerFactory  - Quartz scheduler 'dufy_test' initialized from default resource file in Quartz package: 'quartz.properties'
10:22:35,497 [main] INFO  org.quartz.impl.StdSchedulerFactory  - Quartz scheduler version: 2.2.1
10:22:35,531 [main] INFO  com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource  - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1bqrhg09w1in8fcy1gr7r0t|39a054a5, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1bqrhg09w1in8fcy1gr7r0t|39a054a5, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://140.143.205.128:3306/c_test?characterEncoding=utf8&useSSL=true, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
10:22:36,368 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Freed 0 triggers from 'acquired' / 'blocked' state.
10:22:36,412 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Recovering 0 jobs that were in-progress at the time of the last shut-down.
10:22:36,412 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Recovery complete.
10:22:36,434 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Removed 0 'complete' triggers.
10:22:36,455 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX  - Removed 0 stale fired job entries.
10:22:36,497 [main] INFO  org.quartz.core.QuartzScheduler  - Scheduler dufy_test_$_NON_CLUSTERED started.
10:22:36,497 [main] INFO  quartz.demo.SimpleTriggerTest  - Job结束
10:22:36,891 [dufy_test_Worker-1] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:22:40,273 [dufy_test_Worker-2] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:22:45,273 [dufy_test_Worker-3] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:22:50,269 [dufy_test_Worker-4] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:22:55,274 [dufy_test_Worker-5] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:23:00,275 [dufy_test_Worker-6] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:23:05,269 [dufy_test_Worker-7] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:23:10,272 [dufy_test_Worker-8] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:23:15,404 [dufy_test_Worker-9] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类
10:23:20,365 [dufy_test_Worker-10] INFO  quartz.demo.RAMJob  - 我也不知道这个啥时候执行,反正这个是Job 的实现类

从日志中我们可以看出,任务是以每5s的频率执行的,执行了10个周期,与上边的定义.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(10,5))的一致,任务结束

 

到此,一个基本的Quartz任务调度demo就结束了,下一期我们继续讲解Quartz与Spring的整合

谢谢!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158525.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月13日 下午12:00
下一篇 2022年7月13日 下午12:00


相关推荐

  • rs232接口_RS232串口通信:接口定义、标准接法详细说明,一看就懂了

    rs232接口_RS232串口通信:接口定义、标准接法详细说明,一看就懂了九针串口即 RS232 接口 个人计算机上的通讯接口之一 由电子工业协会 ElectronicIn EIA 所制定的异步传输标准接口 通常 RS232 接口以 9 个引脚 DB9 或是 25 个引脚 DB25 的形态出现 一般个人计算机上会有两组 RS232 接口 分别称为 COM1 和 COM2 它被广泛用于计算机串行接口外设连接 连接电缆和机械 电气特性

    2026年3月19日
    2
  • pycharm需要安装哪些库_python编程

    pycharm需要安装哪些库_python编程好久没用python,竟然连怎么在Pycharm新建项目都忘了…????(。﹏。*)项目解释器选择自带的python还是自动创建虚拟环境还是使用Anaconda里面的虚拟环境

    2022年8月28日
    6
  • php tp框架,tp框架是什么意思

    php tp框架,tp框架是什么意思tp 框架是 ThinkPHP 框架的缩写 ThinkPHP 框架是为了简化企业级应用开发和敏捷 WEB 应用开发而诞生的 最早诞生于 2006 年初 2007 年元旦正式更名为 ThinkPHP 并且遵循 Apache2 开源协议发布 本文操作环境 windows10 DellG3 ThinkPHP6 tp 框架是 ThinkPHP 框架的缩写 ThinkPHP 是为了简化企业级应用开发和敏捷 WEB 应用开发而诞生的 最早诞生

    2026年3月19日
    2
  • 东软始业教育内容提纲(2020)(后附题目)

    东软始业教育内容提纲(2020)(后附题目)东软始业教育内容提纲(后附题目)——2012年8月修正版写在前面:至各位兄弟姐妹,希望大家都能顺利通过!有些题目略微有些变动,总体内容不变。后面的题目绝大多数都在列了,剩余的注意搜索关键字,在前面提纲部分一定有!在百度上搜索一次只能搜索三页,建议大家先下载下来,准备好再开始考试,这样可以全篇搜索。40分的极致不是我的追求,38分这个绝对可以有!1)

    2022年5月10日
    49
  • 弗曼学习法,你在用吗?

    弗曼学习法,你在用吗?今天简单的谈论一下弗曼学习法,是被学术界认为最niubi的学习方法。理查德.弗曼(1918-1988)1965年获得诺贝尔物理学奖,美籍犹太人,也是最早提出纳米的人。之所以以他的名字命名改学习方法,想必不用说大家也都知道了,总之很厉害一个人就是了。 弗曼学习法的原理,可以用一句话来概括(透过现象看本质),比方说我们刚学习、接触一个知识点,按照正常的逻辑就是去学会怎么使用它就行了,而带来的弊端就是,当时,亦或者一段时间内我们能记得,但是随着时间加长,没有使用过这个知识点,我们便会很快就忘记了。因为我

    2022年6月13日
    40
  • vueThink权限配置

    vueThink权限配置

    2021年10月11日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号