quartz的简单使用

本文档介绍了Quartz在Java中的使用,包括初始化调度器、定义Job类、创建触发器、任务调度、简单和复杂触发器的配置、日历排除特定日期、监听器的应用以及触发器优先级设置。通过实例详细解析了Quartz的各种操作,帮助读者掌握其核心功能。
1、quartz的简单使用
1、首先引入一个调度器schedule
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
2、计算下次的运行时间
Date runTime = evenMinuteDate(new Date());
3、定义一个与job相关的类(该类需实现Job接口)

​ job1为任务的名字,group为任务的组

JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build();
4、创建一个触发器
Trigger trigger = newTrigger().withIdentity("trigger1","group1").startAt(runTime).build();
5、告诉调度器使用触发器
sched.scheduleJob(job, trigger);
6、启动调度程序
sched.start();

​ 可选,线程休眠65秒

Thread.sleep(65L * 1000L);
2、简单触发器的使用
获取下一次的时间
Date startTime = DateBuilder.nextGivenSecondDate(null, 15);
简单触发器
SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger1", "group1").startAt(startTime).build();
job3将运行11次(运行一次,再重复10次,每次相隔10秒)
job = newJob(SimpleJob.class).withIdentity("job3", "group1").build();

trigger = newTrigger().withIdentity("trigger3", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).build();
同一个任务可以被多个触发器调度
job5运行一次,在五分钟之后运行
trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1")
    .startAt(futureDate(5, IntervalUnit.MINUTE)).build();
job6无限制运行,每隔40秒运行一次
trigger = newTrigger().withIdentity("trigger6", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInSeconds(40).repeatForever()).build();
job7重复20次,每5分钟重复一次
trigger = newTrigger().withIdentity("trigger7", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20)).build();
添加任务到调度器
sched.addJob(job, true);
手动触发任务
sched.triggerJob(jobKey("job8", "group1"));
重新调度任务
trigger = newTrigger().withIdentity("trigger7", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20)).build();

ft = sched.rescheduleJob(trigger.getKey(), trigger);
关闭任务
sched.shutdown(true);
获取显示更多详细信息
SchedulerMetaData metaData = sched.getMetaData();
打印任务名(实现了job接口的类的execute()使用)
JobKey jobKey = context.getJobDetail().getKey();
3、复杂触发器的使用
// jobs会在调度器执行start()方法后被唤醒
// job1在20秒执行
JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?"))
        .build();
// job2会在每两分钟的15秒执行任务
job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build();
//job3会在8-17点每两分钟执行一次
trigger = newTrigger().withIdentity("trigger3", "group1").withSchedule(cronSchedule("0 0/2 8-17 * * ?")).build();
//job5会在每月1号,15的上午10点执行
trigger = newTrigger().withIdentity("trigger5", "group1").withSchedule(cronSchedule("0 0 10am 1,15 * ?")).build();
//job6仅在工作日每分0秒、30秒执行
trigger = newTrigger().withIdentity("trigger6", "group1").withSchedule(cronSchedule("0,30 * * ? * MON-FRI"))
    .build();
//job7仅在周末每分0秒、30秒执行
trigger = newTrigger().withIdentity("trigger7", "group1").withSchedule(cronSchedule("0,30 * * ? * SAT,SUN"))
    .build();
传递参数

1、将初始化参数传到job中

job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Green");
job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);

2、需在job类中定义参数

public static final String FAVORITE_COLOR = "favorite color";
public static final String EXECUTION_COUNT = "count";

​ 获取并打印传递的参数

JobKey jobKey = context.getJobDetail().getKey();
JobDataMap data = context.getJobDetail().getJobDataMap();
String favoriteColor = data.getString(FAVORITE_COLOR);
int count = data.getInt(EXECUTION_COUNT);
任务延迟

1、定义变量

public static final String NUM_EXECUTIONS  = "NumExecutions";

public static final String EXECUTION_DELAY = "ExecutionDelay";
//获取job的数据集合
JobDataMap map = context.getJobDetail().getJobDataMap();
int executeCount = 0;
//判断集合的是否存在改主键
if (map.containsKey(NUM_EXECUTIONS)) {
  executeCount = map.getInt(NUM_EXECUTIONS);
}
executeCount++;
map.put(NUM_EXECUTIONS, executeCount);
long delay = 5000l;
if (map.containsKey(EXECUTION_DELAY)) {
  delay = map.getLong(EXECUTION_DELAY);
}
try {
    //线程休眠
  Thread.sleep(delay);
} catch (Exception ignore) {
  //
}
//任务statefulJob1每3秒中执行一次,但会延迟10秒钟
JobDetail job = newJob(StatefulDumbJob.class).withIdentity("statefulJob1", "group1")
    .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L).build();

SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime)
        .withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();
任务失效
//每3秒执行一次但会延迟10秒,迭代几次后会失效
job = newJob(StatefulDumbJob.class).withIdentity("statefulJob2", "group1")
    .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L).build();

trigger = newTrigger()
    .withIdentity("trigger2", "group1")
    .startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever()
                      .withMisfireHandlingInstructionNowWithExistingCount()) // set misfire instructions
    .build();
处理任务异常

1、处理任务异常并重启任务

JobDetail job = newJob(BadJob1.class).withIdentity("badJob1", "group1").usingJobData("denominator", "0").build();

SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();
private int calculation;
JobKey jobKey = context.getJobDetail().getKey();
JobDataMap dataMap = context.getJobDetail().getJobDataMap();

int denominator = dataMap.getInt("denominator");

// a contrived example of an exception that
// will be generated by this job due to a
// divide by zero error (only on first run) 
try {
  calculation = 4815 / denominator;
} catch (Exception e) {

  JobExecutionException e2 = new JobExecutionException(e);

  dataMap.put("denominator", "1");
    
  e2.setRefireImmediately(true);
  throw e2;
}

2、处理异常从不重启任务

JobKey jobKey = context.getJobDetail().getKey();

// a contrived example of an exception that
// will be generated by this job due to a 
// divide by zero error
try {
    int zero = 0;
    calculation = 4815 / zero;
} catch (Exception e) {
    JobExecutionException e2 = new JobExecutionException(e);
    e2.setUnscheduleAllTriggers(true);
    throw e2;
}
job = newJob(BadJob2.class).withIdentity("badJob2", "group1").build();

trigger = newTrigger().withIdentity("trigger2", "group1").startAt(startTime)
    .withSchedule(simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
4、日历的使用
1、在任务中排除指定日期

​ 1、将日历添加到任务中

AnnualCalendar holidays = new AnnualCalendar();

//排除指定日期
Calendar fourthOfJuly = new GregorianCalendar(2005, 6, 4);
holidays.setDayExcluded(fourthOfJuly, true);

​ 2、将我们的日历添加到调度器

sched.addCalendar("holidays", holidays, false, false);
2、安排任务从某个日期开始执行

//安排从万圣节开始执行
Date runDate = dateOf(0, 0, 10, 31, 10);

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

SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runDate)
    .withSchedule(simpleSchedule().withIntervalInHours(1).repeatForever()).modifiedByCalendar("holidays").build();
5、监听器的使用
监听一个任务执行让另一个任务执行
JobDetail job = newJob(SimpleJob1.class).withIdentity("job1").build();
Trigger trigger = newTrigger().withIdentity("trigger1").startNow().build();
//开启监听器
JobListener listener = new Job1Listener();
Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getKey());
sched.getListenerManager().addJobListener(listener, matcher);
// schedule the job to run
sched.scheduleJob(job, trigger);
sched.start();
监听器配置
public class Job1Listener implements JobListener {

  public String getName() {
    return "job1_to_job2";
  }
	//任务即将被执行
  public void jobToBeExecuted(JobExecutionContext inContext) {
   
  }
	//任务被否决,不能执行
  public void jobExecutionVetoed(JobExecutionContext inContext) {
   
  }
	//任务已经被执行了
  public void jobWasExecuted(JobExecutionContext inContext, JobExecutionException inException) {
   
    // 创建任务job2
    JobDetail job2 = newJob(SimpleJob2.class).withIdentity("job2").build();

    Trigger trigger = newTrigger().withIdentity("job2Trigger").startNow().build();

    try {
      // schedule the job to run!
      inContext.getScheduler().scheduleJob(job2, trigger);
    } catch (SchedulerException e) {
      e.printStackTrace();
    }

  }

}
6、触发器的优先级
// Calculate the start time of all triggers as 5 seconds from now
Date startTime = futureDate(5, IntervalUnit.SECOND);

// 优先级为1,并且在5秒钟之后重复
Trigger trigger1 = newTrigger().withIdentity("Priority1Trigger5SecondRepeat").startAt(startTime)
    .withSchedule(simpleSchedule().withRepeatCount(1).withIntervalInSeconds(5)).withPriority(1).forJob(job).build();

// 优先级默认为5
Trigger trigger2 = newTrigger().withIdentity("Priority5Trigger10SecondRepeat").startAt(startTime)
    .withSchedule(simpleSchedule().withRepeatCount(1).withIntervalInSeconds(10)).forJob(job).build();

// 优先级为10,并且在15秒钟之后重复
Trigger trigger3 = newTrigger().withIdentity("Priority10Trigger15SecondRepeat").startAt(startTime)
    .withSchedule(simpleSchedule().withRepeatCount(1).withIntervalInSeconds(15)).withPriority(10).forJob(job)
    .build();

// 告诉调度器使用这些触发器
sched.scheduleJob(job, trigger1);
sched.scheduleJob(trigger2);
sched.scheduleJob(trigger3);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值