1、Quartz简介及应用场景
2、Quartz简单触发器 SimpleTrigger介绍
3、Quartz表达式触发器CronTirgger介绍
4、Quartz中参数传递
5、Spring task Vs Quartz
1. Quartz介绍
任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,
“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
简单来说就是实现“计划(或定时)任务”的系统,例如:订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品
2. Quartz的触发器
触发器用来告诉调度程序作业什么时候触发。框架提供了5种触发器类型,但两个最常用的SimpleTrigger和CronTrigger。
五种类型的Trigger(定时器)
SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。
场景:
SimpleTrigger:执行N次,重复N次
CronTrigger:几秒 几分 几时 哪日 哪月 哪周 哪年,执行
3. 存储方式
RAMJobStore(内存作业存储类型)和JDBCJobStore(数据库作业存储类型),两种方式对比如下:
优点 缺点
RAMJobStore 不要外部数据库,配置容易,运行速度快 因为调度程序信息是存储在被分配给JVM的内存里面,
所以,当应用程序停止运行时,所有调度信息将被丢失。
另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制
JDBCJobStor 支持集群,因为所有的任务信息都会保存 运行速度的快慢取决与连接数据库的快慢
到数据库中,可以控制事物,还有就是如
果应用服务器关闭或者重启,任务信息都
不会丢失,并且可以恢复因服务器关闭或
者重启而导致执行失败的任务
图解quartz工作流程
quartz相关表达式
在线生成表达式网址:http://cron.qqe2.com/
导入pom
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-aspects</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>org.quartz-scheduler</groupId> 7 <artifactId>quartz</artifactId> 8 <version>2.2.1</version> 9 </dependency> 10 <dependency> 11 <groupId>org.quartz-scheduler</groupId> 12 <artifactId>quartz-jobs</artifactId> 13 <version>2.2.1</version> 14 </dependency>
创建作业类RamJob
1 package com.yuan.quartz01.job; 2 3 import org.quartz.Job; 4 import org.quartz.JobDataMap; 5 import org.quartz.JobExecutionContext; 6 import org.quartz.JobExecutionException; 7 8 public class RamJob implements Job { 9 10 11 @Override 12 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 13 System.out.println("定时任务具体执行的业务逻辑代码。。。"); 14 JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); 15 System.out.println(jobDataMap.get("name").toString() + ":" + jobDataMap.get("level").toString() + ":" + jobDataMap.get("job").toString()); 16 } 17 }
每次执行 * 长时间,每次间隔 * 长时间
1 package com.yuan.quartz01.quartz; 2 3 4 import com.yuan.quartz01.job.RamJob; 5 import org.quartz.*; 6 import org.quartz.impl.StdSchedulerFactory; 7 8 import static org.quartz.JobBuilder.newJob; 9 10 11 /** 12 * 入门案例 13 */ 14 public class Demo1 { 15 16 17 public static void main(String[] args) throws Exception { 18 // 调度器 19 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); 20 Scheduler scheduler = schedulerFactory.getScheduler(); 21 // 作业类 22 JobDetail jobDetail = newJob(RamJob.class) 23 .withIdentity("job1","group1") 24 .withDescription("this is a job1") 25 .build(); 26 // 触发器 27 Trigger trigger = (Trigger)TriggerBuilder.newTrigger() 28 // 一共执行3次,每6秒执行一次 29 .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,6)) 30 .withIdentity("trigger1", "group1") 31 .withDescription("this is a trigger1") 32 .build(); 33 // 调度器组装作业类及触发器 34 scheduler.scheduleJob(jobDetail,trigger); 35 //启用调度器 36 scheduler.start(); 37 38 39 } 40 41 }
效果
1 package com.yuan.quartz01.quartz; 2 3 4 import com.yuan.quartz01.job.RamJob; 5 import org.quartz.*; 6 import org.quartz.impl.StdSchedulerFactory; 7 8 import static org.quartz.JobBuilder.newJob; 9 10 /** 11 * 表达式触发器 12 * 定时定点执行 13 */ 14 public class Demo2 { 15 16 17 public static void main(String[] args) throws Exception { 18 // 调度器 19 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); 20 Scheduler scheduler = schedulerFactory.getScheduler(); 21 // 作业类 22 JobDetail jobDetail = newJob(RamJob.class) 23 .withIdentity("job1","group1") 24 .withDescription("this is a job1") 25 .build(); 26 // 触发器 27 Trigger trigger = (Trigger)TriggerBuilder.newTrigger() 28 .withSchedule(CronScheduleBuilder.cronSchedule("0 17 19 * * ?")) 29 .withIdentity("trigger1", "group1") 30 .withDescription("this is a trigger1") 31 .build(); 32 // 调度器组装作业类及触发器 33 scheduler.scheduleJob(jobDetail,trigger); 34 //启用调度器 35 scheduler.start(); 36 37 38 } 39 40 }
效果图
1 package com.yuan.quartz01.quartz; 2 3 4 import com.yuan.quartz01.job.RamJob; 5 import org.quartz.*; 6 import org.quartz.impl.StdSchedulerFactory; 7 8 import static org.quartz.JobBuilder.newJob; 9 10 /** 11 * 定时任务参数传递问题 12 */ 13 public class Demo4 { 14 15 16 public static void main(String[] args) throws Exception { 17 // 调度器 18 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); 19 Scheduler scheduler = schedulerFactory.getScheduler(); 20 // 作业类 21 JobDetail jobDetail = newJob(RamJob.class) 22 .withIdentity("job1","group1") 23 .withDescription("this is a job1") 24 .build(); 25 JobDataMap jobDataMap = jobDetail.getJobDataMap(); 26 jobDataMap.put("name","小源"); 27 jobDataMap.put("level","顶级"); 28 jobDataMap.put("job","**"); 29 30 // 触发器 31 Trigger trigger = (Trigger)TriggerBuilder.newTrigger() 32 .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) 33 .withIdentity("trigger1", "group1") 34 .withDescription("this is a trigger1") 35 .build(); 36 // 调度器组装作业类及触发器 37 scheduler.scheduleJob(jobDetail,trigger); 38 //启用调度器 39 scheduler.start(); 40 41 42 } 43 44 }
效果图
Spring task
优点:无需整合spring,作业类中就可以调用业务service
缺点:单线程;不能做数据存储型的定时任务
Quartz
优点:多线程;可以做数据存储型的定时任务,维护性高;
缺点:需要整合spring,不能直接调用业务层service;
线程论证代码
Spring task代码
1 package com.yuan.quartz01.task; 2 3 import org.springframework.scheduling.annotation.Scheduled; 4 import org.springframework.stereotype.Component; 5 6 import java.text.SimpleDateFormat; 7 import java.util.Date; 8 9 @Component 10 public class SpringTask { 11 12 @Scheduled(cron = "0/10 * * * * ?") 13 public void xxx(){ 14 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 15 System.err.println(format.format(new Date())+" : 这是一个spring task..."); 16 17 try { 18 Thread.sleep(20*1000); 19 System.out.println("模拟正在处理大数据...."); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 } 24 25 }
Quartz01Application
1 package com.yuan.quartz01; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.scheduling.annotation.EnableScheduling; 6 7 @EnableScheduling 8 @SpringBootApplication 9 public class Quartz01Application { 10 11 public static void main(String[] args) { 12 SpringApplication.run(Quartz01Application.class, args); 13 } 14 15 }
spring task 单线程
结果是spring task中的定时任务变成了30s执行一次
RamJob
1 package com.yuan.quartz01.quartz; 2 3 import com.yuan.quartz01.job.RamJob; 4 import org.quartz.*; 5 import org.quartz.impl.StdSchedulerFactory; 6 7 import static org.quartz.JobBuilder.newJob; 8 9 public class Demo5 { 10 11 public static void main(String[] args) throws SchedulerException { 12 SchedulerFactory factory = new StdSchedulerFactory(); 13 // 调度器创建 14 Scheduler scheduler = factory.getScheduler(); 15 16 // 具体定时任务需要执行的代码 17 JobDetail jobDetail = newJob(RamJob.class) 18 .withIdentity("job2", "group1") 19 .withIdentity("这是一个作业类案例") 20 .build(); 21 22 Trigger trigger = (Trigger) TriggerBuilder.newTrigger() 23 // 每10s执行一次 24 .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) 25 // 触发器标识 26 .withIdentity("trigger2", "group1") 27 .withDescription("这是一个触发器") 28 .build(); 29 30 // 调度工厂绑定作业类及触发器 31 scheduler.scheduleJob(jobDetail, trigger); 32 scheduler.start(); 33 } 34 }
变更RamJob
1 package com.yuan.quartz01.job; 2 3 import org.quartz.Job; 4 import org.quartz.JobDataMap; 5 import org.quartz.JobExecutionContext; 6 import org.quartz.JobExecutionException; 7 8 import java.text.SimpleDateFormat; 9 import java.util.Date; 10 11 public class RamJob implements Job { 12 13 14 @Override 15 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 16 // System.out.println("定时任务具体执行的业务逻辑代码。。。"); 17 // JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); 18 // System.out.println(jobDataMap.get("name").toString() + ":" + jobDataMap.get("level").toString() + ":" + jobDataMap.get("job").toString()); 19 20 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 21 System.err.println(format.format(new Date())+" : 基于RAM的quartz调度框架定时任务..."); 22 23 try { 24 Thread.sleep(20*1000); 25 System.out.println("模拟正在处理大数据...."); 26 } catch (InterruptedException e) { 27 e.printStackTrace(); 28 } 29 } 30 }
运行结果
原文:https://www.cnblogs.com/ly-0919/p/11967447.html