首页 > 代码库 > quartz入门
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 = Mschedulerorg.quartz.scheduler.instanceId=AUTO#============================================================================# Configure ThreadPool#============================================================================org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount=20org.quartz.threadPool.threadPriority=5org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true#============================================================================# Configure JobStore#============================================================================org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.useProperties=falseorg.quartz.jobStore.dataSource=myDSorg.quartz.jobStore.tablePrefix=qrtz_org.quartz.jobStore.isClustered=trueorg.quartz.jobStore.maxMisfiresToHandleAtATime=1org.quartz.jobStore.misfireThreshold=60000#============================================================================# Configure Datasources#============================================================================org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driverorg.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCorg.quartz.dataSource.myDS.user=rootorg.quartz.dataSource.myDS.password=123456org.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入门