java - 恢复卡住的 quartz 作业

标签 java multithreading quartz-scheduler

我面临着一些被卡住的 quartz 工作,例如尝试永远连接。我正在使用一种方案,其想法是我可以检测这些卡住的作业,因为它们的触发器的 nextFiretime 已经过去很久了。然后,我尝试通过中断它们来停止这些线程。然而,中断似乎不起作用,线程仍在运行,而没有更新 nextFiretime。 如何正确打断它们?

职位代码:

protected AtomicReference<Thread> runningThread = null;

/*
 * (non-Javadoc)
 * 
 * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
 */
@Override
public void execute(JobExecutionContext context)
        throws JobExecutionException
{
    runningThread = new AtomicReference<Thread>();
    try {
        this.runningThread.set(Thread.currentThread());
    } finally { 
        runningThread.set(null); 
    }
}

/*
 * (non-Javadoc)
 * 
 * @see org.quartz.InterruptableJob#interrupt()
 */
@Override
public void interrupt() throws UnableToInterruptJobException
{
    Thread thread = runningThread.getAndSet(null);
    if (thread != null)
        thread.interrupt();
}

用于中断的实际jobscheduler代码:

public int interruptLongRunningJobs(int ms) {
    int jobsInterrupted = 0;
    String jobsInterruptedList = "";

    Date limitInThePast = new Date(System.currentTimeMillis() - ms);

    Scheduler scheduler = this.getJobScheduler();
    // All scheduled jobs
    try {
        for (String groupName : scheduler.getJobGroupNames()) {
            for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                final List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);

                Date nextFireTime = null;
                if (triggers.size() > 0)
                {
                    nextFireTime = triggers.get(0).getNextFireTime();

                    if(nextFireTime != null) {
                        if(nextFireTime.before(limitInThePast)) {
                            String jobString = jobDetail.getKey() + "@" + jobDetail.getJobClass().getSimpleName();
                            logger.debug("JobScheduler::interruptLongRunningJobs interrupting: " + jobString);

                            scheduler.interrupt(jobDetail.getKey());

                            if(!jobsInterruptedList.isEmpty()) {
                                jobsInterruptedList += ", ";
                            }
                            jobsInterruptedList += jobString;
                            ++jobsInterrupted;
                        }
                    }
                }
            }
        }
    } catch (SchedulerException e) {
        logger.debug("JobScheduler::interruptLongRunningJobs failed: " + e.getMessage());
    }

    if(jobsInterrupted>0) {
        logger.debug("JobScheduler::interruptLongRunningJobs interrupted jobs#= " + jobsInterrupted);

        emailSomething("JobScheduler::interruptLongRunningJobs interrupted jobs#= " + jobsInterrupted, 
                "These jobs have been interrupted and canceled because they exceeded the maximum running time as detected by triggers with nextFireTime in the past:\r\n" +  
                jobsInterruptedList
        );
    }
    return jobsInterrupted;
}

最佳答案

问题是我仅在某些子类中实现(复制粘贴)了 public voidexecute 中的逻辑,而这些子类是当时的焦点。我更改了 public voidexecute 的代码,以便所有子类现在都可以轻松使用该逻辑。

@Override
public void execute(JobExecutionContext context)
        throws JobExecutionException
{
    runningThread = new AtomicReference<Thread>();
    try {
        this.runningThread.set(Thread.currentThread());
        reallyExecute(context);
    } finally { 
        runningThread.set(null); 
    }
}

关于java - 恢复卡住的 quartz 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42626762/

相关文章:

java - 服务并发请求的 Tomcat 服务器

java - 从树数据结构打印纯文本树(java)

java - 使用itext java向pdf添加 anchor

java - -Dwebdriver.chrome.driver 中的 -D 是什么意思

javascript - 即使在用户通过 javascript 导航离开后,ASP.NET 是否继续可靠地处理请求?

android - 在嵌套 fragment 中运行多个 AsyncTasks 时挂起线程,这会使应用变慢

java - 交叉同步块(synchronized block)

quartz-scheduler - 如何手动指定 Quartz JobStoreTX 的数据库连接

java - 寻找可扩展的 "at"实现

cron - 月底前 7 天的 Quartz 调度程序