java quartz 单线程_Quartz 并发/单线程

本文通过示例展示了如何使用 Java Quartz 配置调度器以实现单线程和多线程执行任务。重点讲解了 `@DisallowConcurrentExecution` 注解以及 `ThreadPool` 的配置,以防止并发执行和控制任务执行顺序。同时,探讨了 `@PersistJobDataAfterExecution` 注解在任务数据持久化中的作用。
摘要由CSDN通过智能技术生成

org.quartz.scheduler.instanceName = MyScheduler

org.quartz.threadPool.threadCount = 5

org.quartz.jobStore.class =org.quartz.simpl.RAMJobStore

/*

* Copyright 2005 - 2009 Terracotta, Inc.

*

* Licensed under the Apache License, Version 2.0 (the "License"); you may not

* use this file except in compliance with the License. You may obtain a copy

* of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

* License for the specific language governing permissions and limitations

* under the License.

*

*/

package org.quartz.examples.example5;

import java.util.Date;

import org.quartz.DisallowConcurrentExecution;

import org.quartz.Job;

import org.quartz.JobDataMap;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.quartz.PersistJobDataAfterExecution;

/**

A dumb implementation of Job, for unit testing purposes.

@author James House

*/

@PersistJobDataAfterExecution

@DisallowConcurrentExecution

public class StatefulDumbJob implements Job {

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

Constants.

public static final String NUM_EXECUTIONS = "NumExecutions";

public static final String EXECUTION_DELAY = "ExecutionDelay";

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

Constructors.

public StatefulDumbJob() {

}

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*

Interface.

/**

Called by the {@link org.quartz.Scheduler} when a {@link org.quartz.Trigger} fires that is associated with the Job.

@throws JobExecutionException if there is an exception while executing the job.

*/

public void execute(JobExecutionContext context) throws JobExecutionException {

System.err.println("---" + context.getJobDetail().getKey() + " executing.[" + new Date() + "]");

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) {

}

System.err.println(" -" + context.getJobDetail().getKey() + " complete (" + executeCount + ").");

}

}

/*

* Copyright 2005 - 2009 Terracotta, Inc.

*

* Licensed under the Apache License, Version 2.0 (the "License"); you may not

* use this file except in compliance with the License. You may obtain a copy

* of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

* License for the specific language governing permissions and limitations

* under the License.

*

*/

package org.quartz.examples.example5;

import static org.quartz.JobBuilder.newJob;

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;

import static org.quartz.TriggerBuilder.newTrigger;

import static org.quartz.DateBuilder.*;

import java.util.Date;

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.SchedulerFactory;

import org.quartz.SchedulerMetaData;

import org.quartz.SimpleTrigger;

import org.quartz.impl.StdSchedulerFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/**

* Demonstrates the behavior of StatefulJobs, as well as how misfire instructions affect the firings of triggers of StatefulJob s - when the jobs take longer to execute that the frequency of the trigger's repitition.

*

*

While the example is running, you should note that there are two triggers with identical schedules, firing identical jobs. The triggers "want" to fire every 3 seconds, but the jobs take 10 seconds to execute. Therefore, by the time the jobs complete their execution, the triggers have already "misfired" (unless the scheduler's "misfire threshold" has been set to more than 7 seconds). You should see that one of the jobs has its misfire instruction set to SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT, which causes it to fire immediately, when the misfire is detected. The other trigger uses the default "smart policy" misfire instruction, which causes the trigger to advance to its next fire time (skipping those that it has missed) - so that it does not refire immediately, but rather at the next scheduled time.

*

* @author Chris Bonham

*/

public class MisfireExample {

public void run() throws Exception {

Logger log = LoggerFactory.getLogger(MisfireExample.class);

log.info("------- Initializing -------------------");

// First we must get a reference to a scheduler

SchedulerFactory sf = new StdSchedulerFactory();

Scheduler sched = sf.getScheduler();

log.info("------- Initialization Complete -----------");

log.info("------- Scheduling Jobs -----------");

// jobs can be scheduled before start() has been called

// get a "nice round" time a few seconds in the future...

Date startTime = nextGivenSecondDate(null, 15);

// statefulJob1 will run every three seconds

// (but it will delay for ten seconds)

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();

Date ft = sched.scheduleJob(job, trigger);

log.info(job.getKey() + " will run at: " + ft + " and repeat: " + trigger.getRepeatCount() + " times, every " + trigger.getRepeatInterval() / 1000 + " seconds");

log.info("------- Starting Scheduler ----------------");

// jobs don't start firing until start() has been called...

sched.start();

log.info("------- Started Scheduler -----------------");

try {

// sleep for ten minutes for triggers to file....

Thread.sleep(600L * 1000L);

} catch (Exception e) {

}

log.info("------- Shutting Down ---------------------");

sched.shutdown(true);

log.info("------- Shutdown Complete -----------------");

SchedulerMetaData metaData = sched.getMetaData();

log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");

}

public static void main(String[] args) throws Exception {

MisfireExample example = new MisfireExample();

example.run();

}

}

@PersistJobDataAfterExecution

此标记说明在执行完Job的execution方法后保存JobDataMap当中固定数据,在默认情况下 也就是没有设置 @PersistJobDataAfterExecution的时候 每个job都拥有独立JobDataMap

否则改任务在重复执行的时候具有相同的JobDataMap

/*

* Copyright 2005 - 2009 Terracotta, Inc.

*

* Licensed under the Apache License, Version 2.0 (the "License"); you may not

* use this file except in compliance with the License. You may obtain a copy

* of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

* License for the specific language governing permissions and limitations

* under the License.

*

*/

package com.quartz.demo.example6;

import java.util.Date;

import org.quartz.DisallowConcurrentExecution;

import org.quartz.Job;

import org.quartz.JobDataMap;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.quartz.JobKey;

import org.quartz.PersistJobDataAfterExecution;

@PersistJobDataAfterExecution

@DisallowConcurrentExecution

public class BadJob1 implements Job {

public BadJob1() {

}

public void execute(JobExecutionContext context) throws JobExecutionException {

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

JobDataMap dataMap = context.getJobDetail().getJobDataMap();

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

System.out.println("---" + jobKey + " executing at " + new Date() + " with denominator " + denominator);

denominator++;

dataMap.put("denominator", denominator);

}

}

/*

* Copyright 2005 - 2009 Terracotta, Inc.

*

* Licensed under the Apache License, Version 2.0 (the "License"); you may not

* use this file except in compliance with the License. You may obtain a copy

* of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

* License for the specific language governing permissions and limitations

* under the License.

*

*/

package com.quartz.demo.example6;

import static org.quartz.JobBuilder.newJob;

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;

import static org.quartz.TriggerBuilder.newTrigger;

import static org.quartz.DateBuilder.*;

import java.util.Date;

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.SchedulerFactory;

import org.quartz.SimpleTrigger;

import org.quartz.impl.StdSchedulerFactory;

public class JobExceptionExample {

public void run() throws Exception {

// First we must get a reference to a scheduler

SchedulerFactory sf = new StdSchedulerFactory();

Scheduler sched = sf.getScheduler();

// jobs can be scheduled before start() has been called

// get a "nice round" time a few seconds in the future...

Date startTime = nextGivenSecondDate(null, 2);

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

SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();

Date ft = sched.scheduleJob(job, trigger);

//任务每2秒执行一次 那么在BadJob1的方法中拿到的JobDataMap的数据是共享的.

//这里要注意一个情况: 就是JobDataMap的数据共享只针对一个BadJob1任务。

//如果在下面在新增加一个任务 那么他们之间是不共享的 比如下面

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

SimpleTrigger trigger2 = newTrigger().withIdentity("trigger1", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();

//这个job2与job执行的JobDataMap不共享

sched.scheduleJob(job2, trigger2);

sched.start();

try {

// sleep for 30 seconds

Thread.sleep(30L * 1000L);

} catch (Exception e) {

}

sched.shutdown(false);

}

public static void main(String[] args) throws Exception {

JobExceptionExample example = new JobExceptionExample();

example.run();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值