文章插图
前言项目中遇到一个,需要 客户自定任务启动时间 的需求 。原来一直都是在项目里硬编码一些定时器,所以没有学习过 。
很多开源的项目管理框架都已经做了Quartz的集成 。我们居然连这么常用得东西居然没有做成模块化,实在是不应该 。
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由JAVA开发,可以用来执行定时任务,类似于java.util.Timer 。但是相较于Timer,Quartz增加了很多功能:
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
- http://www.quartz-scheduler.org/documentation/
- http://www.quartz-scheduler.org/api/2.3.0/index.html
- 任务 Job : 需要实现的任务类,实现 execute() 方法,执行后完成任务 。
- 触发器 Trigger : 包括 SimpleTrigger 和 CronTrigger 。
- 调度器 Scheduler : 任务调度器,负责基于 Trigger触发器,来执行 Job任务 。
文章插图
Demo按照官网的 Demo,搭建一个纯 maven 项目,添加依赖:
<!-- 核心包 --><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>
新建一个任务,实现了 org.quartz.Job 接口:public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("任务被执行了 。。。");}}
main 方法,创建调度器、jobDetail 实例、trigger 实例、执行:public static void main(String[] args) throws Exception {// 1.创建调度器 SchedulerSchedulerFactory factory = new StdSchedulerFactory();Scheduler scheduler = factory.getScheduler();// 2.创建JobDetail实例,并与MyJob类绑定(Job执行内容)JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();// 3.构建Trigger实例,每隔30s执行一次Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(30).repeatForever()).build();// 4.执行,开启调度器scheduler.scheduleJob(job, trigger);System.out.println(System.currentTimeMillis());scheduler.start();//主线程睡眠1分钟,然后关闭调度器TimeUnit.MINUTES.sleep(1);scheduler.shutdown();System.out.println(System.currentTimeMillis());}
日志打印情况:文章插图
JobDetailJobDetail 的作用是绑定 Job,是一个任务实例,它为 Job 添加了许多扩展参数 。
文章插图
每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除 。
为什么设计成JobDetail + Job,不直接使用Job?
JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中 。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题 。
而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以 规避并发访问 的问题 。
JobExecutionContext
- 当 Scheduler 调用一个 job,就会将 JobExecutionContext 传递给 Job 的 execute() 方法;
推荐阅读
- 超跑|3.5秒破百的V12怪兽!阿斯顿马丁新超跑限量249辆已卖空
- 穿衣搭配|海清母子同框,“蛋妞”身材纤细很绅士,她留超短发很俏皮
- 华为|269元 李小龙力荐华为S-Tag运动传感器:详细记录跑步数据
- iPhone长篇笔记文章,怎么截成超长图片分享给别人?
- 超磁分离水体净化技术 超磁分离技术
- 穿衣搭配|50+想要穿出高级感,快来和这位姐妹学习,普通单品都能超神
- 勒布朗·詹姆斯|这就是超巨!半职业联赛席无空座,苦等詹姆斯12小时,球迷:都值得
- TCP/IP攻击详细解释
- 孕早期阴超有什么危害
- 孕12周前总共做15次b超