我有一些石英作业来处理一些数据。我在写这些作业时使用了InterruptableJob接口。我必须给这些作业添加一个中断功能。当用户按下终止按钮时,调用这个方法。
@Override
protected void immediatelyTerminate() {
try {
String fireInstanceIdToKillJob = "";
Scheduler scheduler = schedulerFactory.getScheduler();
List<JobExecutionContext> currentlyExecutingJobs = scheduler.getCurrentlyExecutingJobs();
for(JobExecutionContext jec : currentlyExecutingJobs) {
if(jec.getJobDetail().getKey().getName().contains(specificJobKey) {
fireInstanceIdToKillJob = jec.getFireInstanceId();
}
}
scheduler.interrupt(fireInstanceIdToKillJob);
} catch (Exception e) {
logger.debug("error in immediatelyTerminate() method:" + e);
}
}
调度器.interrupt调用interrupt()方法,这个方法在一个类中被重写,而这个类也有执行方法。有重载中断方法的类是这样的。
private Thread threadToKill;
@Override
public void execute() {
threadToKill = Thread.currentThread();
}
@Override
public void interrupt() throws UnableToInterruptJobException {
try {
threadToKill.interrupt();
} catch (Exception e) {
System.out.println("Exception handled "+e);
}
}
但这段代码并没有终止工作,而是继续工作 threadToKill.interrupt(); 这一行并没有真正终止运行中的工作。
如何终止正在运行的作业?
几年前,我就实现了这个非常相同的功能。
中断一个线程不会杀死它,也不会停止它。. 它只是激活了一个标志,让线程知道它已经被 问 来停止。大多数内部方法会检查这一点,并抛出一个 InterruptedException
让你去捕捉它,但有些线程会很乐意忽略任何中断请求。所以,要靠作业本身来检测这种情况并采取相应的行动。
基本上,你的 interrupt()
方法应该设置一些标志到 true
而你的工作应该不时地检查这个标志,当它注意到这个标志处于活动状态时,就停止它正在做的事情。这就是我如何实现它。
public clas SomeJob implements InterruptableJob {
protected AtomicBoolean stopFlag = new AtomicBoolean(false);
@Override
public void execute(final JobExecutionContext context) {
for (Item item : listOfItems) { // whatever long tasks(s) you are doing,
if (stopFlag.get()) { // just check for this on every main loop
logger.error("Job interrupted! Leaving at item: "+item);
break;
}
performTask(item);
}
cleanUp();
return;
}
private void performTask(Item item) {
for(....) { // another loop,
if (stopFlag.get()) { // another check
// ....
return; // or break, depending on each case
}
someInternalProcessing(...);
}
}
@Override
protected void interrupt() {
stopFlag.set(true);
}
}
就是这样 只要确保在中止之前清理、关闭连接等。