quartz入门
Posted koushr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了quartz入门相关的知识,希望对你有一定的参考价值。
本文介绍的是不与spring整合的quartz的使用。
代码(基于quartz2.3.0版本):
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
import java.util.Date; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class QuartzTest { public static void main(String[] args) { try { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobDetail = JobBuilder.newJob(SimpleQuartzJob.class).withIdentity("jobDetail", "jobDetailGroup") .build(); // 立即执行,5秒间隔无限制重复: Trigger trigger = TriggerBuilder.newTrigger()// .withIdentity("myTrigger", "myTriggerGroup") // 每5s执行一次任务 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)).startNow().build(); // 从现在开始10秒后执行一次: Date date = new Date(); trigger = TriggerBuilder.newTrigger().startAt(new Date(date.getTime() + 10 * 1000)).build(); // 从现在开始立即执行,每5秒重复,直到30秒后: Date date1 = new Date(); trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) .startNow().endAt(new Date(date1.getTime() + 30 * 1000)).build(); scheduler.scheduleJob(jobDetail, trigger); // fire triggers scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } } public class SimpleQuartzJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println(context); } }
quartz主要用到3个接口:Scheduler接口、JobDetail接口以及Trigger接口。
上面代码用StdSchedulerFactory的getDefaultScheduler()静态方法获取Scheduler实例(内部实现是创建StdSchedulerFactory工厂对象之后再获取Scheduler对象),用JobBuilder和TriggerBuilder的一系列方法获得JobDetail实例和Trigger实例,再把JobDetail实例和Trigger实例绑定到Scheduler实例上,然后调用Scheduler实例的start()方法触发定时器。
值得注意的是,JobBuilder的newJob(Class <? extends Job> jobClass)静态方法中要传的Class对象对应的org.quartz.Job实现类必须是public的,实测用内部类不行。
在本例中,获取Trigger对象时,TriggerBuilder对象的withSchedule(ScheduleBuilder scheBuilder)方法传入的参数是SimpleScheduleBuilder实例,这样将产生一个SimpleTrigger实例,这个实例只能满足基本情况。如果使用情况更复杂的话,需要使用CronTrigger,在withSchedule()方法中传入一个CronScheduleBuilder实例即可。SimpleTrigger和CronTrigger是Trigger接口的两个实现类。
CronTrigger利用用cron表达式可以满足各种各样的定时需求。关于cron表达式的用法,www.cnblogs.com/be-come/p/6165293.html讲的非常详细。
quartz存储与持久化:
quartz提供两种基本作业存储类型。第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储。
在默认情况下quartz使用第一种存储类型,即将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。
如果确实需要持久化任务调度信息,则可以把这些信息保存到数据库中,这样,系统崩溃重新启动后任务的调度信息会得以恢复。其实,如果是单机的quartz,那么保存任务调度信息基本没什么意义,保存任务调度信息最主要是用在quartz集群的情况下,在quartz集群中,我们希望在某一时刻只有一个服务器的quartz触发,具体是哪台服务器不要求。首先,需要我们手动建表,建表语句在quartz-2.3.0.jar包中,jar包解压后,在quartz-2.3.0\\org\\quartz\\impl\\jdbcjobstore文件夹下可以找到在各种数据库中建表的sql脚本,从中挑选出对应的数据库脚本执行即可。之后,需要添加quartz.properties配置文件,内容如下:
#============================================================================ # Configure scheduler #============================================================================ # org.quartz.scheduler.instanceName = Mscheduler org.quartz.scheduler.instanceId=AUTO #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount=20 org.quartz.threadPool.threadPriority=5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.useProperties=false org.quartz.jobStore.dataSource=myDS org.quartz.jobStore.tablePrefix=qrtz_ org.quartz.jobStore.isClustered=true org.quartz.jobStore.maxMisfiresToHandleAtATime=1 org.quartz.jobStore.misfireThreshold=60000 #============================================================================ # Configure Datasources #============================================================================ org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driver org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC org.quartz.dataSource.myDS.user=root org.quartz.dataSource.myDS.password=123456 org.quartz.dataSource.myDS.maxConnections=5
org.quartz.threadPool.class用来配置quartz工作时用的线程池,默认是org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount用来配置线程池中的线程数量,默认为10个线程,优先级默认为5
org.quartz.jobStore.class配置成org.quartz.impl.jdbcjobstore.JobStoreTX,应用自己管理事务,如果想用应用服务器管理事务,则应配置成org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass的值根据数据库不同而不同,mysql数据库对应org.quartz.impl.jdbcjobstore.StdJDBCDelegate,postgresql数据库对应org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.isClustered,是否启用集群,应用集群部署的话则值为true
解释一下这里为什么要配置数据源,因为是要把任务调度信息保存到数据库当中,所以肯定要配置数据源连接数据库。这里的数据源配置可以和应用的主数据源一致,也可以不一致,也可以共用一个配置。
以上是关于quartz入门的主要内容,如果未能解决你的问题,请参考以下文章