Scheduler 每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题(jobDetail的实例也是新的)

Quzrtz 定时任务默认都是并发执行,不会等待上一次任务执行完毕,只要间隔时间到就会执行,如果定时任务执行太长,会长时间占用资源,导致其它任务堵塞

@DisallowConcurrentExecution: job类上,禁止并发地执行同一个job定义 (JobDetail定义的)的多个实例。

  • scheduler:可以理解为定时任务的工作容器或者说是工作场所,所有定时任务都是放在里面工作,可以开启和停止。
  • trigger:可以理解为是定时任务任务的工作规则配置,例如说,没个几分钟调用一次,或者说指定每天那个时间点执行。
  • jobDetail:定时任务的信息,例如配置定时任务的名字,群组之类的。
  • job:定时任务的真正的业务处理逻辑的地方。

简单示例

TestClient.Java

import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class TaskClient {    public static void main(String[] args) {        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)                .withIdentity("job1", "group1")  //设置JOB的名字和组                .build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1", "trigger1")                .startNow()                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)                        .repeatForever())                .build();        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            scheduler.scheduleJob(jobDetail,trigger);            scheduler.start();        } catch (SchedulerException ex) {            ex.printStackTrace();        }    }}

TaskJob.Java

import cn.hutool.core.date.DateUtil;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class TaskJob implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("TaskJob => " + DateUtil.now());    }}

usingJobData

通过 usingJobData 往定时任务中传递参数

import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class TaskClient {    public static void main(String[] args) {        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)                .withIdentity("job1", "group1")                .usingJobData("job","jobDetail1.JobDataMap.Value")                .build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1", "trigger1")                .usingJobData("trigger","trigger.JobDataMap.Value")                .startNow()                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)                        .repeatForever())                .build();        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            scheduler.scheduleJob(jobDetail,trigger);            scheduler.start();        } catch (SchedulerException ex) {            ex.printStackTrace();        }    }}

TaskJob.java

import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class TaskJob implements Job {    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();        JobDataMap triggerMap = context.getTrigger().getJobDataMap();        JobDataMap mergeMap = context.getMergedJobDataMap();        System.out.println("jobDataMap => " + jobDataMap.getString("job"));        System.out.println("triggerMap => " + triggerMap.getString("trigger"));        System.out.println("mergeMap => " + mergeMap.getString("trigger"));    }}

通过 属性赋值

import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class TaskClient {    public static void main(String[] args) {        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)                .withIdentity("job1", "group1")                .usingJobData("job","jobDetail1.JobDataMap.Value")                .usingJobData("name","jobDetail1.name.Value") //通过 setName 自动赋值                .build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1", "trigger1")                .usingJobData("trigger","trigger.JobDataMap.Value")                .usingJobData("name","trigger.name.Value")  //如果 Trigger 有值,会覆盖 JobDetail                .startNow()                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)                        .repeatForever())                .build();        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            scheduler.scheduleJob(jobDetail,trigger);            scheduler.start();        } catch (SchedulerException ex) {            ex.printStackTrace();        }    }}
import org.quartz.*;public class TaskJob implements Job {    private String name;    public void setName(String name) {        this.name = name;    }    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        System.out.println("name => " + name);    }}

非并发执行

@DisallowConcurrentExecution job类上,禁止并发地执行同一个job定义 (JobDetail定义的)的多个实例。

import cn.hutool.core.date.DateUtil;import org.quartz.*;@DisallowConcurrentExecutionpublic class TaskJob implements Job {    @Override    public void execute(JobExecutionContext context) {        System.out.println("Time => " + DateUtil.now());        try {            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

@PersistJobDataAfterExecution
持久化JobDetail中的JobDataMap(对 trigger 中的 datamap 无效),如果一个任务不是

import cn.hutool.core.date.DateUtil;import org.quartz.*;//持久化JobDetail中的JobDataMap(对 trigger 中的 datamap 无效),如果一个任务不是@PersistJobDataAfterExecutionpublic class TaskJob implements Job {    @Override    public void execute(JobExecutionContext context) {        JobDataMap triggerMap = context.getJobDetail().getJobDataMap();        triggerMap.put("count", triggerMap.getInt("count") + 1);        System.out.println("Time => " + DateUtil.now() + " count =>" + triggerMap.getInt("count"));    }}

Client

import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class TaskClient {    public static void main(String[] args) {        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)                .withIdentity("job1", "group1")                .usingJobData("job","jobDetail1.JobDataMap.Value")                .usingJobData("name","jobDetail1.name.Value") //通过 setName 自动赋值                .usingJobData("count",0) //通过 setName 自动赋值                .build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("trigger1", "trigger1")                .usingJobData("trigger","trigger.JobDataMap.Value")                .usingJobData("name","trigger.name.Value")  //如果 Trigger 有值,会覆盖 JobDetail                .startNow()                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)                        .repeatForever())                .build();        try {            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();            scheduler.scheduleJob(jobDetail,trigger);            scheduler.start();        } catch (SchedulerException ex) {            ex.printStackTrace();        }    }}