基础

纯java实现
特点:
强大的调度功能, 可以持久化调度
灵活的应用方式
分布式和集群能力

所用到的设计模式
Builder创建者模式
Factory工厂模式
组件模式
链式写法

image.png

核心类和接口

v2.2.3

任务 job接口 业务

  1. public class PrintWordsJob implements Job{
  2. @Override
  3. public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  4. // 具体任务逻辑
  5. String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
  6. System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-"
  7. + new Random().nextInt(100));
  8. }
  9. }

JobDetail用来绑定Job,为Job实例提供许多属性:

  • name 任务名
  • group 分组
  • jobClass
  • jobDataMap

生命周期
JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job

JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。 这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

1. JobExecutionContext/JobDataMap
JobExecutionContext中包含了Quartz运行时的环境以及Job本身的详细数据信息。
当Schedule调度执行一个Job的时候,就会将JobExecutionContext传递给该Job的execute()中,Job就可以通过JobExecutionContext对象获取信息。
JobDataMap存储在JobExecutionContext中, 它实现了JDK的Map接口,可以以Key-Value的形式存储数据(存储任何可序列化的对象)。
JobDetail、Trigger都可以使用JobDataMap来设置一些参数或信息,
如:

  1. JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
  2. .usingJobData("jobDetail1", "这个Job用来测试的")
  3. .withIdentity("job1", "group1").build();
  4. Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
  5. .usingJobData("trigger1", "这是jobDetail1的trigger")
  6. .startNow()//立即生效
  7. .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  8. .withIntervalInSeconds(1)//每隔1s执行一次
  9. .repeatForever()).build();//一直执行

Job执行的时候,可以获取到这些参数信息:

  1. @Override
  2. public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  3. System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetail1"));
  4. System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("trigger1"));
  5. String printTime = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(new Date());
  6. System.out.println("PrintWordsJob start at:" + printTime + ", prints: Hello Job-"
  7. + new Random().nextInt(100));
  8. }

2. 给Job实现类设置成员变量和set/get方法
可以不用从jobExecutionContext获取map, 可直接使用成员变量

触发器trigger

Trigger是Quartz的触发器,会去通知Scheduler何时去执行对应Job。

JobKey: job实例的标识
startTime: new Trigger().startAt():表示触发器首次被触发的时间 java.util.Date
endTime:new Trigger().endAt():表示触发器结束触发的时间;

  • SimpleTrigger
    SimpleTrigger可以实现
    • 在一个指定时间段内执行一次作业任务
    • 一个时间段内多次执行作业任务。

下面的程序就实现了程序运行5s后开始执行Job,执行Job 5s后结束执行:

  1. Date startDate = new Date();
  2. startDate.setTime(startDate.getTime() + 5000);
  3. Date endDate = new Date();
  4. endDate.setTime(startDate.getTime() + 5000);
  5. Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
  6. .usingJobData("trigger1", "这是jobDetail1的trigger")
  7. .startNow()//立即生效
  8. .startAt(startDate)//表示触发器首次被触发的时间;
  9. .endAt(endDate)//表示触发器结束触发的时间;
  10. .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  11. .withIntervalInSeconds(1)//每隔1s执行一次
  12. .repeatForever()// 不断,重复
  13. ).build();//一直执行
  • CronTrigger

CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的

  1. CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
  2. .usingJobData("trigger1", "这是jobDetail1的trigger")
  3. .startNow()//立即生效
  4. .startAt(startDate)
  5. .endAt(endDate)
  6. .withSchedule(CronScheduleBuilder.cronSchedule("* 30 10 ? * 1/5 2018"))
  7. .build();

调度器scheduler (核心)

image.png

  1. public class MyScheduler {
  2. public static void main(String[] args) throws SchedulerException, InterruptedException {
  3. // 1、创建调度器Scheduler
  4. SchedulerFactory schedulerFactory = new StdSchedulerFactory();
  5. Scheduler scheduler = schedulerFactory.getScheduler();
  6. // 2、创建JobDetail实例,并与PrintWordsJob类绑定(Job执行内容)
  7. JobDetail jobDetail = JobBuilder.newJob(PrintWordsJob.class)
  8. .withIdentity("job1", "group1").build();
  9. // 3、构建Trigger实例,每隔1s执行一次
  10. Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggerGroup1")
  11. .startNow()//立即生效
  12. .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  13. .withIntervalInSeconds(1)//每隔1s执行一次
  14. .repeatForever()).build();//一直执行
  15. //4、执行
  16. scheduler.scheduleJob(jobDetail, trigger);
  17. System.out.println("--------scheduler start ! ------------");
  18. scheduler.start();
  19. //睡眠
  20. TimeUnit.MINUTES.sleep(1);
  21. scheduler.shutdown();
  22. System.out.println("--------scheduler shutdown ! ------------");
  23. }
  24. }


配置及更多

https://www.w3cschool.cn/quartz_doc/