有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用来自InterruptableJob接口的重写中断方法终止当前运行的quartz作业?

我有一些处理数据的工作。我在编写这些作业时使用了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()方法,该类还具有execute方法。重写中断方法的类如下所示:

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。中断();行实际上并没有终止正在运行的作业

我怎样才能终止这项工作


共 (1) 个答案

  1. # 1 楼答案

    几年前,我实现了同样的功能

    Interrupting a thread does not kill it nor stop it。它只是激活一个标志,这样线程就知道它已被要求停止。大多数内部方法都会对此进行检查,并抛出一个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);
        }
    }
    

    就这样。在中止之前,只需确保清理、关闭连接等