Quartz之InterruptableJob

12 篇文章 0 订阅
[b]问题1 由于业务需要,停止Quartz中正在执行的任务[/b]
[color=red]Quartz:你的任务类只需要实现InterruptableJob类就可以了 :lol:
只要实现一个方法:interrupt(),在这个方法中进行标记的改变,在执行中进行这个标记判断
就可实现中断任务了,另外在调度器上调用方法:sched.interrupt(job.getKey());[/color]
在查看Quartz文档中已经有说明了,如下:

The interface to be implemented by Jobs that provide a mechanism for having their execution interrupted. It is NOT a requirement for jobs to implement this interface - in fact, for most people, none of their jobs will.

Interrupting a Job is very analogous in concept and challenge to normal interruption of a Thread in Java.

The means of actually interrupting the Job must be implemented within the Job itself (the interrupt() method of this interface is simply a means for the scheduler to inform the Job that a request has been made for it to be interrupted). The mechanism that your jobs use to interrupt themselves might vary between implementations. However the principle idea in any implementation should be to have the body of the job's execute(..) periodically check some flag to see if an interruption has been requested, and if the flag is set, somehow abort the performance of the rest of the job's work. An example of interrupting a job can be found in the java source for the class org.quartz.examples.DumbInterruptableJob. It is legal to use some combination of wait() and notify() synchronization within interrupt() and execute(..) in order to have the interrupt() method block until the execute(..) signals that it has noticed the set flag.

If the Job performs some form of blocking I/O or similar functions, you may want to consider having the Job.execute(..) method store a reference to the calling Thread as a member variable. Then the Implementation of this interfaces interrupt() method can call interrupt() on that Thread. Before attempting this, make sure that you fully understand what java.lang.Thread.interrupt() does and doesn't do. Also make sure that you clear the Job's member reference to the Thread when the execute(..) method exits (preferably in a finally block.

See Example 7 (org.quartz.examples.example7.DumbInterruptableJob) for a simple implementation demonstration

具体代码如下:
DumbInterruptableJob.java

package org.quartz.examples.example7;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.InterruptableJob;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.UnableToInterruptJobException;


/**
* @author <a href="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a>
* @author Bill Kratzer
*/
public class DumbInterruptableJob implements InterruptableJob {

// logging services
private static Logger _log = LoggerFactory.getLogger(DumbInterruptableJob.class);

// has the job been interrupted?
private boolean _interrupted = false;

// job name
private JobKey _jobKey = null;

private static int counts = 0;


public DumbInterruptableJob() {
}


public void execute(JobExecutionContext context)
throws JobExecutionException {

_jobKey = context.getJobDetail().getKey();
_log.error("任务Key: " + _jobKey + " 执行时间: " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));

try {

for (int i = 0; i < 4; i++) {
try {
Thread.sleep(1000L);
} catch (Exception ignore) {
ignore.printStackTrace();
}

if(_interrupted) {
_log.error("被外界因素停止了这个任务key: " + _jobKey + ",当前执行次数: " + counts);
return; // could also choose to throw a JobExecutionException
// if that made for sense based on the particular
// job's responsibilities/behaviors
}
//执行业务方法
userManager();
}

} finally {
_log.error("任务执行完成key: " + _jobKey + " 执行时间: " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
}
}

private void userManager() {
_log.error("正在执行插入数据库的操作,次数: " + (++counts));
}

public void interrupt() throws UnableToInterruptJobException {
_log.info("外界正在调用调度器停止这个任务key: " + _jobKey);
_interrupted = true;
}
}

InterruptExample.java

package org.quartz.examples.example7;

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;


public class InterruptExample {

public void run() throws Exception {
final Logger log = LoggerFactory.getLogger(InterruptExample.class);

SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();

Date startTime = nextGivenSecondDate(null, 15);

JobDetail job = newJob(DumbInterruptableJob.class)
.withIdentity("interruptableJob1", "group1")
.build();

//当前时间15秒后,每间隔5秒执行一次任务
SimpleTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(startTime)
.withSchedule(simpleSchedule()
.withIntervalInSeconds(5)
.repeatForever())
.build();

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

sched.start();

for(int i=0; i < 10; i++) {
try {
Thread.sleep(7000L);
sched.interrupt(job.getKey());
} catch (Exception e) {
}
}

sched.shutdown(true);

SchedulerMetaData metaData = sched.getMetaData();
log.error("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");

}

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

InterruptExample example = new InterruptExample();
example.run();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值