学习使用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的整合

谢谢!!!

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea社区版连接mysql数据库[通俗易懂]

    idea社区版连接mysql数据库[通俗易懂]社区版默认不支持数据库连接,需要下载一个插件下载之后打开,如下新建一个连接,设置mysql的用户,密码之类另外,需要设置一下时区,不然可能会报错如下之后就可以使用了!

  • PS2有线手柄的SPI协议

    PS2有线手柄的SPI协议1.SPI模式与PS2采用的是SPIMODE3模式。并且使用低位在前方式收发数据。2.请求PS2按键数据想要向PS2请示数据要发送一个请求命令。请求命令如下所示:cmd_require[9]={0x01,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//数据按先低位后高位发送3.接收PS按键数据在发送请求命令的…

  • 渗透测试工具——漏洞扫描工具

    渗透测试工具——漏洞扫描工具安全漏洞产生的原因技术原因软件系统复杂性提高,质量难于控制,安全性降低 公用模块的使用引发了安全问题经济原因“柠檬市场”效应——安全功能是最容易删减的部分环境原因从传统的封闭、静态和可控变为开放、动态和难控 攻易守难安全缺陷安全性缺陷是信息系统或产品自身“与生俱来”的特征,是其“固有成分”安全漏洞是与生俱来的系统设计缺陷Internet从设计时就缺乏安全的总体架构和设计 TCP/IP中的三阶段握手.软件源代码的急剧膨胀Windows951500万行

  • 高效上网教程—如何在线看片找片

    高效上网教程—如何在线看片找片高效上网教程如何在线看片找片一、总结一句话总结:1、电影资源网站推荐?2、在线看片网站推荐?3、看美剧和下载美剧资源推荐?4、字幕下载网站推荐?5、纪录片资源推荐?二、内容在总结中

  • python3 zipfile_Python之zipfile模块的使用[通俗易懂]

    python3 zipfile_Python之zipfile模块的使用[通俗易懂]1、判断是否是zip文件#!/usr/bin/envpython3#encoding:utf-8importzipfilefilenames=[‘tcp_server.py’,’test.py’,’test.zip’]forfilenameinfilenames:print(‘{:>15}{}’.format(filename,zipfile.is_zipfile(fil…

  • f1 score 代码_f1 score loss 实现问题「建议收藏」

    f1 score 代码_f1 score loss 实现问题「建议收藏」在paddle上实现了一个f1loss函数:def_compute_loss(self,dec_output):tp=fluid.layers.sum(fluid.layers.cast(self.label*dec_output,dtype=”float32″))tn=fluid.layers.sum(fluid.layers.cast((1-self.label)*…

    2022年10月14日

发表回复

您的电子邮箱地址不会被公开。

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