【原创】Quartz代码详解
阅读目录
- 简单介绍
- 章节1:Quartz简单实例
- 章节2:Job、JobDetail、JobBuilder
- 章节3:Trigger、TriggerBuilder
- 章节4:Scheduler
- 章节5:JobListener、SchedulerListener、TriggerListener
- 章节6:Cron表达式
- 章节7:程序示例
- 章节8:参考链接
简单介绍
- Scheduler:调度器,将Job和Trigger关联起来;
- Job :需要执行的作业;
- Trigger :触发器,指定执行的时间,主要包括两种方式:
一、Quartz简单实例
二、Job、JobDetail、JobBuilder
- Job - an interface to be implemented by components that you wish to have executed by the scheduler.
- JobDetail - used to define instances of Jobs.
- JobBuilder - used to define/build JobDetail instances, which define instances of Jobs.
Job
public class HelloJob implements Job {public HelloJob() {}public void execute(JobExecutionContext context)throws JobExecutionException{System.err.println("Hello! HelloJob is executing.");}}
JobDetail
JobDetail job = newJob(HelloJob.class).withIdentity("myJob", "group1") // name "myJob", group "group1".build();
- key;
- JobClass;
- JobDataMap;等
JobBuilder
三、Trigger、TriggerBuilder
SimpleTrigger
CronTrigger
TriggerBuilder
通过forJob()方法将Trigger和指定的Job绑定
- 在使用JobBuilder创建JobDetail时,通过方法withIdentity()指定了JobDetail的JobKey;
- 这里通过TriggerBuilder的forJob()同样指定了JobKey;
四、Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.schedeleJob(Job,trigger)
scheduler.start();
scheduler.shutdown();
五、JobListener、SchedulerListener、TriggerListener
六、Cron表达式
* ("all values") - used to select all values within a field. For example, "" in the minute field means *"every minute".
? ("no specific value") - useful when you need to specify something in one of the two fields in which the character is allowed, but not the other. For example, if I want my trigger to fire on a particular day of the month (say, the 10th), but don't care what day of the week that happens to be, I would put "10" in the day-of-month field, and "?" in the day-of-week field. See the examples below for clarification.
- - used to specify ranges. For example, "10-12" in the hour field means "the hours 10, 11 and 12".
, - used to specify additional values. For example, "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".
/ - used to specify increments. For example, "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". You can also specify '/' after the '' character - in this case '' is equivalent to having '0' before the '/'. '1/3' in the day-of-month field means "fire every 3 days starting on the first day of the month".
L ("last") - has different meaning in each of the two fields in which it is allowed. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". You can also specify an offset from the last day of the month, such as "L-3" which would mean the third-to-last day of the calendar month. When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing/unexpected results.
W ("weekday") - used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days.
The 'L' and 'W' characters can also be combined in the day-of-month field to yield 'LW', which translates to *"last weekday of the month"*.
- # - used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means"the third Friday of the month" (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.
七、程序示例
AbstractSchedule类:抽象基类
package com.sssppp.TimerSchedule.quartz.schedule;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import com.sssppp.TimerSchedule.quartz.listeners.MyJobListener;
import com.sssppp.TimerSchedule.quartz.listeners.MySchedulerListener;
import com.sssppp.TimerSchedule.quartz.listeners.MyTriggerListener;
public abstract class AbstractSchedule {
public Scheduler scheduler = null;
private static final String JOB_GROUPNAME = "MY_JOB_GROUP";
private static final String TRIGGER_GROUPNAME = "MY_TRIGGER_GROUP";
/**
* 初始化Scheduler,并添加Listeners
*/
public AbstractSchedule() {
try {
if (scheduler == null) {
System.out.println("Begin init scheduler...");
try {
Properties props = new Properties();
props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,
"org.quartz.simpl.SimpleThreadPool");
props.put("org.quartz.threadPool.threadCount", "100");// 同时100个线程运行
props.put("org.quartz.jobStore.misfireThreshold", "180000");// trigger过期30分钟内还有效
StdSchedulerFactory factory = new StdSchedulerFactory();
factory.initialize(props);
scheduler = factory.getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
}
scheduler.getListenerManager().addJobListener(new MyJobListener());
scheduler.getListenerManager().addSchedulerListener(
new MySchedulerListener());
scheduler.getListenerManager().addTriggerListener(
new MyTriggerListener());
}
} catch (Exception e) {
System.err.println("Init scheduler failed, error message :" + e);
}
}
public abstract Scheduler handleJob(String jobName, String triggerName,
String cronStr);
@SuppressWarnings({ "unchecked", "rawtypes" })
public void scheduleJob(String jobName, String triggerName, String express,
Class clazz) {
JobDetail job = null;
CronTrigger trigger = null;
try {
job = JobBuilder.newJob(clazz).withIdentity(jobName, JOB_GROUPNAME)
.build();
trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerName, TRIGGER_GROUPNAME)
.forJob(jobName, JOB_GROUPNAME)
.withSchedule(CronScheduleBuilder.cronSchedule(express))
.build();
} catch (Exception e) {
System.err.println("scheduler ParseException!" + e);
}
Date date = null;
try {
date = scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
System.err.println("scheduler SchedulerException!" + e);
}
System.out.println(job.getKey().toString()
+ " has been scheduled to run at: " + date
+ " and repeat based on expression: "
+ trigger.getCronExpression());
}
/**
* 创建Job和Trigger,并使用scheduler将job和Trigger进行关联
*
* @param jobName
* @param triggerName
* @param express
* :cronStr表达式
* @param clazz
* :job的class
* @param params
* :Job使用的参数
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void scheduleJobWithParams(String jobName, String triggerName,
String express, Class clazz, Map<String, Object> params) {
JobDetail job = null;
CronTrigger trigger = null;
try {
job = JobBuilder.newJob(clazz)
.withIdentity(new JobKey(jobName, JOB_GROUPNAME))
.usingJobData(new JobDataMap(params)).build();
trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerName, TRIGGER_GROUPNAME)
.forJob(jobName, JOB_GROUPNAME)
.withSchedule(CronScheduleBuilder.cronSchedule(express))
.build();
} catch (Exception e) {
System.err.println("scheduler ParseException!" + e);
}
Date date = null;
try {
date = scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
System.err.println("scheduler SchedulerException!" + e);
}
System.out.println(job.getKey().toString()
+ " has been scheduled to run at: " + date
+ " and repeat based on expression: "
+ trigger.getCronExpression());
}
/**
* Starts the Scheduler's threads that fire Triggers
*/
public void startJob() {
try {
this.scheduler.start();
} catch (SchedulerException e) {
System.err.println("trigger job error!" + e);
}
}
public boolean stopJob(String jobName) {
boolean b = false;
JobKey jobkey = new JobKey(jobName, JOB_GROUPNAME);
try {
if (this.scheduler.checkExists(jobkey)) {
b = this.scheduler.deleteJob(jobkey);
System.out.println("Stop Job[" + jobName + "] success.");
}
} catch (SchedulerException e) {
System.err.println("Stop job fail.");
e.printStackTrace();
}
return b;
}
public void shutdownScheduler() {
try {
this.scheduler.shutdown(true);
System.out.println("Shutdown scheduler success.");
} catch (SchedulerException e) {
System.err.println("Shutdown Scheduler fail.");
e.printStackTrace();
}
}
}
package com.sssppp.TimerSchedule.quartz.schedule;
import java.util.HashMap;
import java.util.Map;
import org.quartz.Scheduler;
import com.sssppp.TimerSchedule.quartz.Jobs.MyJob;
public class MyJobSchedule extends AbstractSchedule {
private static MyJobSchedule myJobSchedule = new MyJobSchedule();
private MyJobSchedule() {
}
public static MyJobSchedule getInstance() {
return myJobSchedule;
}
@Override
public Scheduler handleJob(String jobName, String triggerName,
String cronStr) {
Map<String, Object> params = new HashMap<String, Object>();
params.put(MyJob.JOB_PARAM_KEY, "This is myJob param");
scheduleJobWithParams(jobName, triggerName, cronStr, MyJob.class, params);
startJob();
return this.scheduler;
}
}
package com.sssppp.TimerSchedule.quartz.Jobs;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.ibm.icu.text.SimpleDateFormat;
public class MyJob implements Job {
public final static String JOB_PARAM_KEY = "jobParam";
@Override
public void execute(JobExecutionContext jobexecutioncontext)
throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 获取传递给Job的参数
String param = (String) jobexecutioncontext.getJobDetail()
.getJobDataMap().get(JOB_PARAM_KEY);
System.out.println("Now exec MyJob,param【" + param + "】, time:"
+ sdf.format(new Date()));
}
}
package com.sssppp.TimerSchedule.quartz;
import com.sssppp.TimerSchedule.quartz.schedule.MyJobSchedule;
public class QuartzManager {
private static final QuartzManager quartzManager = new QuartzManager();
private static final String MY_JOB_NAME = "MY_JOB_NAME";
private static final String MY_TRIGGER_NAME = "MY_TRIGGER_NAME";
private static final String MY_JOB_CRONSTR = "0/5 * * * * ?";
private QuartzManager() {
}
public static QuartzManager getInstance() {
return quartzManager;
}
public void startMyJob() {
MyJobSchedule.getInstance().handleJob(MY_JOB_NAME, MY_TRIGGER_NAME,
MY_JOB_CRONSTR);
}
public void stopMyJobAndShutdownScheduler() {
MyJobSchedule.getInstance().stopJob(MY_JOB_NAME);
MyJobSchedule.getInstance().shutdownScheduler();
}
}
TestCase.java
package com.sssppp.TimerSchedule.quartz;
public class TestCase {
@SuppressWarnings("static-access")
public static void main(String[] args) throws InterruptedException {
QuartzManager.getInstance().startMyJob();
Thread.currentThread().sleep(12 * 1000);
QuartzManager.getInstance().stopMyJobAndShutdownScheduler();
}
}
八、参考链接
附件列表
- 1.png
- 1_2.png
- 1_3.png
- 2.png
- 3.png
- a2.png
转载于:https://www.cnblogs.com/ssslinppp/p/5055524.html
【原创】Quartz代码详解相关推荐
- socket 获取回传信息_Luat系列官方教程5:Socket代码详解
文章篇幅较长,代码部分建议横屏查看,或在PC端打开本文链接.文末依然为爱学习的你准备了专属福利~ TCP和UDP除了在Lua代码声明时有一些不同,其他地方完全一样,所以下面的代码将以TCP长连接的数据 ...
- android生命周期_Android开发 View的生命周期结合代码详解
咱们以TextView控件为例: /** * Created by SunshineBoy on 2020/9/23. */ public class TestTextView extends and ...
- Qt开发技术:QCharts(三)QCharts样条曲线图介绍、Demo以及代码详解
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108022984 各位读者,知识无穷而人力有穷 ...
- Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130150728 各位读者,知识无穷而人力有穷,要么改需 ...
- Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130264470 各位读者,知识无穷而人力有穷,要么改需 ...
- Quartz.Net详解
Quartz.Net详解 代码仓库地址 Gitee:https://gitee.com/bluecusliyou Github:https://github.com/bluecusliyou 零.文章 ...
- yoloV3代码详解(注释)
原文链接:https://www.cnblogs.com/hujinzhou/p/guobao_2020_3_13.html yolo3各部分代码详解(超详细) </h1><div ...
- 【CV】Pytorch一小时入门教程-代码详解
目录 一.关键部分代码分解 1.定义网络 2.损失函数(代价函数) 3.更新权值 二.训练完整的分类器 1.数据处理 2. 训练模型(代码详解) CPU训练 GPU训练 CPU版本与GPU版本代码区别 ...
- html5代码转换为视频,HTML5中的视频代码详解
摘要 腾兴网为您分享:HTML5中的视频代码详解,智学网,云闪付,易推广,小红书等软件知识,以及360win10,流量魔盒,fitbit,上港商城,安卓2.3.7,全民惠,五年级下册英语单词表图片,t ...
最新文章
- GSMA:中国有望成为全球领先的5G市场之一
- 补零对有限长序列频谱及DFT的影响
- 机器学习笔记: Discriminative vs Generative Models
- opencv 中 快速傅里叶变换 FFT
- 终极解密输入网址按回车到底发生了什么
- ASP.NET MVC 相关的社群与讨论区
- qt给exe文件添加图标
- 【Kafka】【未解决】kafka反序列化数据报错jackson2 JsonParseException: Invalid UTF-8 middle byte 0xc0
- windows mysql5.7 忘记密码_Windows下Mysql5.7忘记root密码的解决方法
- XSS-Game level 6
- CenOS7.4内核升级修复系统漏洞
- 海龟绘图两小时上手C语言 - 3 正方形螺旋线
- 数据结构利器之私房STL
- SEO HTML语义化
- 络达1562系统深度睡眠后RTC唤醒应用
- 台式计算机对比评测报告,正常台式电脑测试报告.doc
- Python中scipy库的pearsonr(x, y)的使用
- Android 快应用
- firewalld防火墙配置ip地址伪装和端口转发
- 【erlang】【rebar依赖】添加eredis依赖
热门文章
- access 使用dsn 连接字符串_致正在备考Access的你,学习重点和题库以及b站优课请查收!...
- linux内存管理实验malloc,linux内存管理实验报告.doc
- 【spring boot】 禁用/关闭数据源/DataSource
- java 接口 this参数_Java BiFunction 接口实例
- matplotlib 显示批量图片_chapter4-1 简单数据可视化包Matplotlib整理1
- 信息通信建设工程预算定额_通信建设工程概预算
- 常见的邮件服务器有哪三种,常见邮件服务器的种类有哪些?分别用什么协议?,常见服务器类型...
- 三件套都有什么_床上用品三件套、四件套、21件套都各指什么啊?
- 重启服务器之home下文件全没,小白宝典——树莓派实用工具分享(大神绕路)
- c语言程序设计章节作业网上,C语言程序设计第17章在线测试