1

我在主类中运行一个简单的石英作业,每 30 秒运行一次。

public class Start {
 public static void main(String[] args) throws Exception {    
      SchedulerFactory sf = new StdSchedulerFactory();
      Scheduler sched = sf.getScheduler();
       JobDetail job = newJob(MyJob.class).withIdentity("myJob","XXX").build();
   Trigger trigger = TriggerBuilder.newTrigger()
         .withSchedule(
             SimpleScheduleBuilder.simpleSchedule()
                 .withIntervalInSeconds(30)
             .repeatForever())
                               .build();
    sched.scheduleJob(job, trigger);
     sched.start();
  } 
}

在这里,我正在实施 InterruptableJob 之类的

 public class MyJob implements InterruptableJob {

private volatile boolean isJobInterrupted = false;

private JobKey jobKey = null;

private volatile Thread thisThread;

public MyJob() {
}

@Override
public void interrupt() throws UnableToInterruptJobException {
    // TODO Auto-generated method stub
    System.err.println("calling interrupt:"+thisThread+"==>"+jobKey);
    isJobInterrupted = true;
    if (thisThread != null) {
        // this call causes the ClosedByInterruptException to happen
        thisThread.interrupt();
    }

}

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    // TODO Auto-generated method stub
    thisThread = Thread.currentThread();

    jobKey = context.getJobDetail().getKey();

    System.err.println("calling execute:"+thisThread+"==>"+jobKey);
}
}

现在我试图以各种可能的方式使用另一个主类来停止工作,但没有运气

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

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

        // get a "nice round" time a few seconds in the future...
        Date startTime = nextGivenSecondDate(null, 1);

        JobDetail job = newJob(MyJob.class).withIdentity("myJob", "XXX").build();

        Trigger trigger = TriggerBuilder.newTrigger()
        .withSchedule(
                 SimpleScheduleBuilder.simpleSchedule()
                     .withIntervalInSeconds(30)
                 .repeatForever())
                                   .build();

        sched.scheduleJob(job, trigger);

        sched.start();


            try {
                  // if you want to see the job to finish successfully, sleep for about 40 seconds
                Thread.sleep(60000) ;
                  // tell the scheduler to interrupt our job
                  sched.interrupt(job.getKey());
                  Thread.sleep(3 * 1000L);
                } catch (Exception e) {
                  e.printStackTrace();
                }
                System.err.println("------- Shutting Down --------");

                TriggerKey tk=TriggerKey.triggerKey("myJob","group1");
                System.err.println("tk"+tk+":"+job.getKey());
                sched.unscheduleJob(tk);
                sched.interrupt(job.getKey());
                sched.interrupt("myJob");
                sched.deleteJob(job.getKey());
                sched.shutdown();
                System.err.println("------- Shutting Down ");

                sched.shutdown(false);

                System.err.println("------- Shutdown Complete ");

            System.err.println("------- Shutdown Complete ");

    }
}

谁能告诉我停止工作的正确方法?非常感谢。

4

1 回答 1

7

这个问题似乎回答了你描述的确切问题:

您需要编写一个作业作为 InterruptableJob 的实现。要中断这项工作,您需要处理Scheduler, 并调用interrupt(jobKey<<job name & job group>>)

根据InterruptableJob 文档

由 Jobs 实现的接口,提供中断执行的机制。实现这个接口并不是工作的必要条件——事实上,对于大多数人来说,他们的工作都不会。

中断作业在概念上与 Java 中线程的正常中断非常相似。

实际中断 Job 的方法必须在 Job 本身内部实现(该接口的 interrupt() 方法只是调度程序通知 Job 已请求中断的一种方法)。您的作业用来中断自己的机制可能因实现而异。然而,任何实现中的主要思想应该是让作业的 execute(..) 的主体定期检查一些标志以查看是否已请求中断,如果设置了标志,则以某种方式中止其余部分的性能工作的工作。

强调我的。它是类似的,但不一样。你不应该使用线程(但如果你这样做的话,你Job确实可以......)。

可以在类 org.quartz.examples.DumbInterruptableJob 的 java 源代码中找到中断作业的示例。在interrupt() 和execute(..) 中使用wait() 和notify() 同步的某种组合是合法的,以便让interrupt() 方法阻塞,直到execute(..) 发出它注意到集合的信号旗帜。

因此,我建议阅读文档并查看完整下载中的示例。

于 2013-08-27T14:06:39.423 回答