Quartz知识点总结

简单说明

简单的定时任务使用Timer或者ScheduledExecutorService

quartz支持复杂的定时执行功能。支持ram存储(内存存储)和持久化存储。quartz有分布式和集群能力

简单使用

  1. 获取任务调度器Schedule。任务调度器可以管理任务。
  2. 创建任务实例。使用JobBuilder(任务类.class)创建,会返回一个JobDetail。任务是一个实现了Job,并实现execute方法的类而已,execute方法记录要执行的事情。
  3. 创建触发器Trigger。Trigger是用来指定触发策略的,包括什么时候开始执行、循环多少次、多久执行一次呀,等等。支持链式编程。
  4. 把任务和触发器告诉任务调度器,使用scheduleJob方法来完成。
  5. 使用任务调度器启动任务
  6. 使用任务调度器关闭任务

例子:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SimpleJob implements Job {
   
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
   
        System.out.println("SimpleJob is executing at: " + new java.util.Date());
    }
}
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzExample {
   
    public static void main(String[] args) {
   
        try {
   
            // 1. 获取任务调度器
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 2. 创建任务实例
            JobDetail job = JobBuilder.newJob(SimpleJob.class)
                    .withIdentity("simpleJob", "group1")
                    .build();

            // 3. 创建触发器
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("simpleTrigger", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(10) // 每10秒执行一次
                            .repeatForever()) // 无限重复
                    .build();

            // 4. 把任务和触发器告诉任务调度器
            scheduler.scheduleJob(job, trigger);

            // 5. 使用任务调度器启动任务
            scheduler.start();

            // 让任务运行一段时间
            Thread.sleep(60000); // 60秒

            // 6. 使用任务调度器关闭任务
            scheduler.shutdown();

        } catch (SchedulerException | InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

使用了 Builder 模式(建造者模式):

JobDetail job = JobBuilder.newJob(SimpleJob.class)
.withIdentity("simpleJob", "group1")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("simpleTrigger", "group1")
        .startNow()
        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)
                .repeatForever())
        .build();

Quartz基本的实现原理

  1. job和jobdetail的关系是什么?

Job(任务)是一个接口,表示一个具体的任务。你需要实现这个接口,并在 execute 方法中定义任务的具体逻辑。Job 只关注任务的执行逻辑,即 做什么。

JobDetail(任务详情)JobDetail 是一个类,用于描述任务的详细信息。它包含了任务的元数据,例如任务类、任务名称、任务组、任务数据等。JobDetail 关注任务的 元信息,即 谁来做 和 怎么做。

JobDetail job = JobBuilder.newJob(SimpleJob.class)
        .withIdentity("simpleJob", "group1")
        .build();

这里 JobDetail 描述了任务的详细信息:

  • 任务类是 SimpleJob.class。
  • 任务名称是 “simpleJob”。
  • 任务组是 “group1”。

总结:

  • Job:定义任务的具体逻辑(做什么)。
  • JobDetail:描述任务的元信息(谁来做、怎么做)。
  • 关系:JobDetail 是 Job 的包装器,包含了 Job 的类信息和任务的额外信息。
  • 设计目的:解耦任务逻辑和任务元信息,提高灵活性和可扩展性。
  1. 原理图:

  1. Job、JobDetail和Trigger的关系

Trigger:

  • 一个 Trigger 只能绑定一个 JobDetail。

JobDetail:

  • 一个 JobDetail 可以被多个 Trigger 绑定。相当于是一个Job信息可以被多次使用。

Job:

  • 一个 Job 类可以创建多个 JobDetail 对象。相当于是可以允许多个JobDetail使用一个Job的execute逻辑。
  • 默认情况下,Quartz 每次触发器触发时都会创建一个新的 Job 实例,再去执行execute方法。(这样可以线程安全)

例子:

package com.example;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.*;
import static org.quartz.JobBuilder.newJob;

public class SimpleTriggerMisfireExample {
   
    public static void main(String[] args) throws SchedulerException {
   
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();

        JobDetail job = newJob(MyJob.class)
                .withIdentity("myJob", "group1")
                .storeDurably()
                .build();

        Trigger trigger1 = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(5)
                        .repeatForever())
                .build();

        Trigger trigger2 = TriggerBuilder.newTrigger()
                .withIdentity("trigger2", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(3)
                        .repeatForever())
                .build();

        Set<Trigger> triggers = new HashSet<>();
        triggers.add(trigger1);
        triggers.add(trigger2);

        Map<JobDetail, Set<? extends Trigger>> triggersAndJobs = new HashMap<>();
        triggersAndJobs.put(job, triggers);

        scheduler.scheduleJobs(triggersAndJobs, false);

        System.out.println("调度器启动时间: " + new Date());
        scheduler.start();

        try {
   
            Thread.sleep(60000); // 等待 60 秒
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        scheduler.shutdown();
    }

    public static class MyJob implements Job {
   
        @Override
        public void execute(JobExecutionContext context) {
   
            Trigger trigger = context.getTrigger();
            System.out.println("任务执行开始: " + new Date() +
                    ", Trigger: " + trigger.getKey() +
                    ", 触发时间: " + trigger.getPreviousFireTime());
            try {
   
                Thread.sleep(3000); // 模拟任务执行耗时 3 秒
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            System.out.println("任务执行结束: " + new Date());
        }
    }
}

执行结果:

D:\jdk1.8.0_172\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2021.3.2\lib\idea_rt.jar=55136:D:\IDEA\IntelliJ IDEA 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk1.8.0_172\jre\lib\charsets.jar;D:\jdk1.8.0_172\jre\lib\deploy.jar;D:\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;D:\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;D:\jdk1.8.0_172\jre\lib\ext\dnsns.jar;D:\jdk1.8.0_172\jre\lib\ext\jaccess.jar;D:\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;D:\jdk1.8.0_172\jre\lib\ext\localedata.jar;D:\jdk1.8.0_172\jre\lib\ext\nashorn.jar;D:\jdk1.8.0_172\jre\lib\ext\sunec.jar;D:\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;D:\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;D:\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;D:\jdk1.8.0_172\jre\lib\ext\zipfs.jar;D:\jdk1.8.0_172\jre\lib\javaws.jar;D:\jdk1.8.0_172\jre\lib\jce.jar;D:\jdk1.8.0_172\jre\lib\jfr.jar;D:\jdk1.8.0_172\jre\lib\jfxswt.jar;D:\jdk1.8.0_172\jre\lib\jsse.jar;D:\jdk1.8.0_172\jre\lib\management-agent.jar;D:\jdk1.8.0_172\jre\lib\plugin.jar;D:\jdk1.8.0_172\jre\lib\resources.jar;D:\jdk1.8.0_172\jre\lib\rt.jar;E:\develop\spring\target\classes;C:\Users\Administrator\.m2\repository\org\quartz-scheduler\quartz\2.3.2\quartz-2.3.2.jar;C:\Users\Administrator\.m2\repository\com\mchange\c3p0\0.9.5.4\c3p0-0.9.5.4.jar;C:\Users\Administrator\.m2\repository\com\mchange\mchange-commons-java\0.2.15\mchange-commons-java-0.2.15.jar;C:\Users\Administrator\.m2\repository\com\zaxxer\HikariCP-java7\2.4.13\HikariCP-java7-2.4.13.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-simple\1.7.36\slf4j-simple-1.7.36.jar com.example.SimpleTriggerMisfireExample
[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.simpl.SimpleThreadPool - Job execution threads will use class loader of thread: main
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.2 created.
[main] INFO org
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值