Quartz(1-Job任务界说与使用)

打印 上一主题 下一主题

主题 2040|帖子 2040|积分 6120

根本使用
  1. <dependency>
  2.     <groupId>org.quartz-scheduler</groupId>
  3.     <artifactId>quartz</artifactId>
  4.     <version>2.3.1</version>
  5. </dependency>
复制代码
  1. public class HelloJob implements Job {
  2.     @Override
  3.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  4.         //实际触发时间。例如,计划时间可能是 10:00:00,但如果调度程序太忙,实际触发时间可能是 10:00:03。
  5.         Date fireTime = jobExecutionContext.getFireTime();
  6.         System.out.println("fireTime:" + fireTime);
  7.         //上次触发时间
  8.         Date previousFireTime = jobExecutionContext.getPreviousFireTime();
  9.         System.out.println("previousFireTime:" + previousFireTime);
  10.         //下次触发时间
  11.         Date nextFireTime = jobExecutionContext.getNextFireTime();
  12.         System.out.println("nextFireTime:" + nextFireTime);
  13.         //触发器触发的预定时间。
  14.         Date scheduledFireTime = jobExecutionContext.getScheduledFireTime();
  15.         System.out.println("scheduledFireTime:" + scheduledFireTime);
  16.         JobDetail jobDetail = jobExecutionContext.getJobDetail();
  17.         System.out.println("jobDataMap:" + JSON.toJSONString(jobDetail.getJobDataMap()));
  18.         System.out.println("jobKey:" + JSON.toJSONString(jobDetail.getKey()));
  19.         System.out.println("jobDescription:" + jobDetail.getDescription());
  20.         System.out.println("==================================");
  21.     }
  22.     public static void main(String[] args) throws SchedulerException {
  23.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  24.         JobDetail jobDetail = JobBuilder
  25.                 .newJob(HelloJob.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  26.                 .withIdentity("hello","group1")
  27.                 .withDescription("Quartz测试")
  28.                 .usingJobData("name", "小米")
  29.                 .usingJobData("age", 15)
  30.                 .build();
  31.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  32.         SimpleTrigger trigger = TriggerBuilder.newTrigger()
  33.                 .withIdentity("myTrigger", "group1")
  34.                 .startNow() //立即生效
  35.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  36.                         .withIntervalInSeconds(2) //每2秒执行一次
  37.                         .repeatForever()) //一直执行
  38.                 .build();
  39.         //3.创建schedule实例
  40.         StdSchedulerFactory factory = new StdSchedulerFactory();
  41.         Scheduler scheduler = factory.getScheduler();
  42.         scheduler.start(); //启动
  43.         scheduler.scheduleJob(jobDetail, trigger); // jobDetail和trigger加入调度
  44.     }
  45. }
复制代码
JobExecutionContext

当 Scheduler 调用一个 Job 就会将 JobExecutionContext 通报给 Job 的 execute()方法,Job 能通过 JobExecutionContext 对象访问到 Quartz 运行时候的环境和 Job 本身的明细数据
JobDetail、JobBuilder

方法


  • storeDurably
JobDetails 信息持久化到数据库的时候有一个属性 storeDurably,如果设置为 true 则无论与其关联的 Trigger 是否存在其都会一直存在,否则只要相关联的 trigger 删除掉了其会自动删除掉

  • requestRecovery
请求规复,也就是说当应用发生故障的时候,是否重新实验默认是 false。如果一个 job 是可规复的,并且在其实验的时候,scheduler 发生硬关闭(hard shutdown)(好比运行的历程崩溃了,或者关机了),则当 scheduler 重新启动的时候,该 job 会被重新实验。此时,该 job 的 JobExecutionContext.isRecovering() 返回 true

  • usingJobData、setJobData
添加 Job 数据,每个 JobDetail 内都有一个 JobDataMap,包含了关联到这个 Job 的数据,在 Job 类中,可以通过 context 取出该数据,进行业务流程处置惩罚。

  • withIdentity
给 JobDetail 起一个 Id,方便后面检索

  • withDescription
用来对 job 进行描述,并没有什么实际作用
JobDataMap

JobDetail 是任务的界说,而 Job 是任务的实验逻辑,每一个 JobDetail 都会有一个 JobDataMap,JobDataMap 本质就是一个 Map 的扩展类,可以存储一些任务信息
JobDataMap 获取任务信息
  1. public class HelloJob implements Job {
  2.     @Override
  3.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  4.         JobDetail jobDetail = jobExecutionContext.getJobDetail();
  5.         JobDataMap jobDataMap = jobDetail.getJobDataMap();
  6.         System.out.println("name:" + jobDataMap.getString("name"));
  7.         System.out.println("age:" + jobDataMap.getInt("age"));
  8.         System.out.println("jobKey:" + JSON.toJSONString(jobDetail.getKey()));
  9.         System.out.println("jobDescription:" + jobDetail.getDescription());
  10.         System.out.println("==================================");
  11.     }
  12.     public static void main(String[] args) throws SchedulerException {
  13.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  14.         JobDetail jobDetail = JobBuilder
  15.                 .newJob(HelloJob.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  16.                 .withIdentity("hello","group1")
  17.                 .withDescription("Quartz测试")
  18.                 .usingJobData("name", "小米")
  19.                 .usingJobData("age", 15)
  20.                 .build();
  21.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  22.         SimpleTrigger trigger = TriggerBuilder.newTrigger()
  23.                 .withIdentity("myTrigger", "group1")
  24.                 .startNow() //立即生效
  25.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  26.                         .withIntervalInSeconds(2) //每2秒执行一次
  27.                         .repeatForever()) //一直执行
  28.                 .build();
  29.         //3.创建schedule实例
  30.         StdSchedulerFactory factory = new StdSchedulerFactory();
  31.         Scheduler scheduler = factory.getScheduler();
  32.         scheduler.start(); //启动
  33.         scheduler.scheduleJob(jobDetail, trigger); // jobDetail和trigger加入调度
  34.     }
  35. }
复制代码
实体类获取任务信息
  1. public class HelloJob3 implements Job {
  2.     private String message;
  3.     private Float floatJobValue;
  4.     private Double doubleTriggerValue;
  5.     public String getMessage() {
  6.         return message;
  7.     }
  8.     public void setMessage(String message) {
  9.         this.message = message;
  10.     }
  11.     public Float getFloatJobValue() {
  12.         return floatJobValue;
  13.     }
  14.     public void setFloatJobValue(Float floatJobValue) {
  15.         this.floatJobValue = floatJobValue;
  16.     }
  17.     public Double getDoubleTriggerValue() {
  18.         return doubleTriggerValue;
  19.     }
  20.     public void setDoubleTriggerValue(Double doubleTriggerValue) {
  21.         this.doubleTriggerValue = doubleTriggerValue;
  22.     }
  23.     @Override
  24.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  25.         //打印当前的执行时间 例如 2017-11-22 00:00:00
  26.         Date date = new Date();
  27.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  28.         System.out.println("现在的时间是:" + sf.format(date));
  29.         //打印jobDataMap定义的message的值
  30.         System.out.println("jobDataMap定义的message的值 : " + message);
  31.         //jobDataMap定义的floatJobValue的值
  32.         System.out.println("jobDataMap定义的floatJobValue的值 : " + floatJobValue);   
  33.                 System.out.println("==================================");
  34.     }
  35.     public static void main(String[] args) throws SchedulerException {
  36.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  37.         JobDetail jobDetail = JobBuilder
  38.                 .newJob(HelloJob3.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  39.                 .withIdentity("myJob", "group1") //定义name 和 group
  40.                 .usingJobData("message","hello myJob1") //加入属性到jobDataMap
  41.                 .usingJobData("FloatJobValue",8.88f) //加入属性到jobDataMap
  42.                 .build();
  43.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  44.         SimpleTrigger trigger = TriggerBuilder.newTrigger()
  45.                 .withIdentity("myTrigger", "group1")
  46.                 .startNow() //立即生效
  47.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  48.                         .withIntervalInSeconds(2) //每2秒执行一次
  49.                         .repeatForever()) //一直执行
  50.                 .build();
  51.         //3.创建schedule实例
  52.         StdSchedulerFactory factory = new StdSchedulerFactory();
  53.         Scheduler scheduler = factory.getScheduler();
  54.         scheduler.start(); //启动
  55.         scheduler.scheduleJob(jobDetail,trigger); // jobDetail和trigger加入调度
  56.     }
  57. }
复制代码
注解使用

@PersistJobDataAfterExecution

有状态的 Job 可以理解为多次 Job 调用期间可以持有一些状态信息,这些状态信息存储在 JobDataMap 中,而默认的无状态 Job 每次调用时都会创建一个新的 JobDataMap
留意:没有添加@PersistJobDataAfterExecution 注解,每次调用时都会创建一个新的 JobDataMap,不会累加;添加该注解后,多次调用期间可以持有一些状态信息
  1. @PersistJobDataAfterExecution
  2. public class HelloJob4 implements Job {
  3.     private Integer count;
  4.     public void setCount(Integer count) {
  5.         this.count = count;
  6.     }
  7.     @Override
  8.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  9.         System.out.println(++count);
  10.         jobExecutionContext.getJobDetail().getJobDataMap().put("count", count);
  11.     }
  12.     public static void main(String[] args) throws SchedulerException {
  13.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  14.         JobDetail jobDetail = JobBuilder
  15.                 .newJob(HelloJob4.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  16.                 .withIdentity("myJob", "group1") //定义name 和 group
  17.                 .usingJobData("count",0) //加入属性到jobDataMap
  18.                 .build();
  19.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  20.         SimpleTrigger trigger = TriggerBuilder.newTrigger()
  21.                 .withIdentity("myTrigger", "group1")
  22.                 .startNow() //立即生效
  23.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  24.                         .withIntervalInSeconds(2) //每2秒执行一次
  25.                         .repeatForever()) //一直执行
  26.                 .build();
  27.         //3.创建schedule实例
  28.         StdSchedulerFactory factory = new StdSchedulerFactory();
  29.         Scheduler scheduler = factory.getScheduler();
  30.         scheduler.start(); //启动
  31.         scheduler.scheduleJob(jobDetail,trigger); // jobDetail和trigger加入调度
  32.     }
  33. }
复制代码
@DisallowConcurrentExecution

禁止并发实验多个雷同界说的 JobDetail,这个注解是加在 Job 类上的,但意思并不是不能同时实验多个 Job,而是不能并发实验同一个 Job
例如:同一个 Job 实现类 DemoJob 的两个 JobDetail 实例 A 和 B,设置 A 的定时实验频率为每 1 分钟实验一次,A 的实际运行耗时为 3 分钟,B 的定时实验频率也是每 1 分钟实验一次,B 的实际运行耗时为 30 秒。假如在 07:00 分 00 秒时 A 和 B 同时第一次运行,则到 07:00 分 30 秒时 B 运行结束,此时 A 还在运行中,到 07:01 分 00 秒时 A 和 B 又该实验了,但是由于注解@DisallowConcurrentExecution 的缘故,此时 A 不会再次运行,A 只能在其上一次运行结束后才气再次被调用实验。但是 B 会正常运行(B 不受 A 的影响,注解@DisallowConcurrentExecution 是作用于 JobDetail 实例而不是 Job 实现类)
留意:如果你使用了@PersistJobDataAfterExecution 注解,则猛烈建议你同时使用@DisallowConcurrentExecution 注解,由于当同一个 job(JobDetail)的两个实例被并发实验时,由于竞争,JobDataMap 中存储的数据很可能是不确定的。
使用同一个Job对象
  1. @DisallowConcurrentExecution
  2. public class HelloJob5 implements Job {
  3.     @Override
  4.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  5.         Date date = new Date();
  6.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  7.         System.out.println("现在的时间是:" + sf.format(date));
  8.         JobKey key = jobExecutionContext.getJobDetail().getKey();
  9.         //打印jobDetail 的name
  10.         System.out.println("jobDetail 的name : " + key.getName());
  11.         //打印jobDetail 的group
  12.         System.out.println("jobDetail 的group : " + key.getGroup());
  13.         System.out.println("==============================");
  14.         try {
  15.             Thread.sleep(3000);
  16.         } catch (InterruptedException e) {
  17.             throw new RuntimeException(e);
  18.         }
  19.     }
  20.     public static void main(String[] args) throws SchedulerException {
  21.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  22.         JobDetail jobDetail1 = JobBuilder
  23.                 .newJob(HelloJob5.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  24.                 .withIdentity("group1", "group1") //定义name 和 group
  25.                 .build();
  26.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  27.         SimpleTrigger trigger1 = TriggerBuilder.newTrigger()
  28.                 .withIdentity("myTrigger1", "group1")
  29.                 .startNow() //立即生效
  30.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  31.                         .withIntervalInSeconds(2) //每2秒执行一次
  32.                         .repeatForever()) //一直执行
  33.                 .build();
  34.         //3.创建schedule实例
  35.         StdSchedulerFactory factory = new StdSchedulerFactory();
  36.         Scheduler scheduler = factory.getScheduler();
  37.         scheduler.start(); //启动
  38.         scheduler.scheduleJob(jobDetail1, trigger1); // jobDetail和trigger加入调度
  39.     }
  40. }
复制代码

  • 使用@DisallowConcurrentExecution前
  1. // 运行结果:
  2. 现在的时间是:2024-11-12 00:59:49
  3. jobDetail 的name : group1
  4. jobDetail 的group : group1
  5. ==============================
  6. 现在的时间是:2024-11-12 00:59:52
  7. jobDetail 的name : group1
  8. jobDetail 的group : group1
  9. ==============================
  10. 现在的时间是:2024-11-12 00:59:55
  11. jobDetail 的name : group1
  12. jobDetail 的group : group1
  13. ==============================
复制代码

  • 使用@DisallowConcurrentExecution后
  1. // 运行结果:
  2. 现在的时间是:2024-11-12 01:00:48
  3. jobDetail 的name : group1
  4. jobDetail 的group : group1
  5. ==============================
  6. 现在的时间是:2024-11-12 01:00:50
  7. jobDetail 的name : group1
  8. jobDetail 的group : group1
  9. ==============================
  10. 现在的时间是:2024-11-12 01:00:52
  11. jobDetail 的name : group1
  12. jobDetail 的group : group1
  13. ==============================
复制代码
创建两个 Job 对象
  1. @DisallowConcurrentExecution
  2. public class HelloJob5 implements Job {
  3.     @Override
  4.     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  5.         Date date = new Date();
  6.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  7.         System.out.println("现在的时间是:" + sf.format(date));
  8.         JobKey key = jobExecutionContext.getJobDetail().getKey();
  9.         //打印jobDetail 的name
  10.         System.out.println("jobDetail 的name : " + key.getName());  
  11.         //打印jobDetail 的group
  12.         System.out.println("jobDetail 的group : " + key.getGroup());   
  13.         System.out.println("==============================");
  14.         try {
  15.             Thread.sleep(3000);
  16.         } catch (InterruptedException e) {
  17.             throw new RuntimeException(e);
  18.         }
  19.     }
  20.     public static void main(String[] args) throws SchedulerException {
  21.         //1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
  22.         JobDetail jobDetail1 = JobBuilder
  23.                 .newJob(HelloJob5.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  24.                 .withIdentity("group1", "group1") //定义name 和 group
  25.                 .build();
  26.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  27.         SimpleTrigger trigger1 = TriggerBuilder.newTrigger()
  28.                 .withIdentity("myTrigger1", "group1")
  29.                 .startNow() //立即生效
  30.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  31.                         .withIntervalInSeconds(2) //每2秒执行一次
  32.                         .repeatForever()) //一直执行
  33.                 .build();
  34.         //3.创建schedule实例
  35.         StdSchedulerFactory factory = new StdSchedulerFactory();
  36.         Scheduler scheduler = factory.getScheduler();
  37.         scheduler.start(); //启动
  38.         scheduler.scheduleJob(jobDetail1, trigger1); // jobDetail和trigger加入调度
  39.         JobDetail jobDetail2 = JobBuilder
  40.                 .newJob(HelloJob5.class) //定义Job类为HelloJob类,真正的执行逻辑所在
  41.                 .withIdentity("group2", "group2") //定义name 和 group
  42.                 .build();
  43.         //2.创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
  44.         SimpleTrigger trigger2 = TriggerBuilder.newTrigger()
  45.                 .withIdentity("myTrigger2", "group2")
  46.                 .startNow() //立即生效
  47.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule()
  48.                         .withIntervalInSeconds(3) //每3秒执行一次
  49.                         .repeatForever()) //一直执行
  50.                 .build();
  51.         //3.创建schedule实例
  52.         Scheduler scheduler2 = factory.getScheduler();
  53.         scheduler2.start(); //启动
  54.         scheduler2.scheduleJob(jobDetail2, trigger2); // jobDetail和trigger加入调度
  55.     }
  56. }
复制代码
  1. // 运行结果
  2. 现在的时间是:2024-11-12 01:08:37
  3. 现在的时间是:2024-11-12 01:08:37
  4. jobDetail 的name : group2
  5. jobDetail 的name : group1
  6. jobDetail 的group : group1
  7. jobDetail 的group : group2
  8. ==============================
  9. ==============================
  10. 现在的时间是:2024-11-12 01:08:40
  11. jobDetail 的name : group2
  12. jobDetail 的group : group2
  13. ==============================
  14. 现在的时间是:2024-11-12 01:08:40
  15. jobDetail 的name : group1
  16. jobDetail 的group : group1
  17. ==============================
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表