2017-03-06 5 views
1

예를 들어 영원히 연결하려고 시도하는 등 일부 석영 작업에 직면하고 있습니다. 나는 그 방아쇠가 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 void execute에서 발견 구현했다

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; 
} 

답변

0

, 그 당시에는 초점이 맞았습니다. public void execute에 대한 코드를 변경하여 모든 하위 클래스가 논리를 쉽게 사용하도록했습니다.

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