2012-10-26 90 views
9

我记得我们不能杀死当前正在运行的Quartz Job,但是我们可以中断并在需要时进行布尔检查,无论我们是否需要继续进行后续操作。是否有可能杀死当前正在运行的Quartz Job?

即使当我们实现InterruptableJob并调用scheduler.interrupt来中断作业时,当前执行的作业仍将在服务器中运行。

例:

  1. 命名SQL查询已经通过休眠的工作,这需要很长的时间
  2. 一个已经调用到第三方服务器在第三方服务器需要很长的被触发 时间响应

http://neopatel.blogspot.in/2011/05/quartz-stop-job.html http://forums.terracotta.org/forums/posts/list/3191.page

有人可以纠正我的理解,并解释我们如何杀死或停止“当前”执行的作业?

感谢, 本Kathir

回答

2

正如你说,有没有办法打断“残酷”,在石英一份工作,无论是在JAVA。

您可以将作业的逻辑封装在单独的线程中,并使用ExecutorService运行它。

看看这个例子:https://stackoverflow.com/a/2275596/1517816

假设你QuartzJob是测试类,并在任务类移动你的业务逻辑。

希望它可以帮助

+0

我同意我们不能在JAVA中残酷地杀死Quartz中的工作。另外,同意我们可以通过ExecutorService实现相同的功能。出于我的好奇,它提出了另一个问题,为什么Quartz没有实现ExecutorService,以便他们能够为我们提供一种杀死Job的方法?或者Quartz增强功能中有未来计划。感谢您的澄清,请让我知道您的想法。 – Kathir

+0

为什么它没有实现可能是因为它已经被设计为在jvm中提供这种缺乏的替代方案。它可以与旧的jvms协同工作,如果他们实现了ExecutorService,那么quartz将与最近的jvm和强制项目进行链接 – poussma

+0

可能他们可以通过配置提供额外的或广泛的支持。通过这种方式,他们可以实现提供向下兼容性以及新...我是否缺少任何东西?无论如何感谢您的时间和解释... – Kathir

6

您可以创建新的名为JobBase例如抽象类,它实现IJob接口,并插入抽象方法: public abstract void ExecuteJob(IJobExecutionContext context);

在JobBase可以实现的方法来执行这样的

public abstract class JobBase : IJob,IInterruptableJob 
{ 
    private Thread currentThread; 
    private ILog logger; 
    public JobBase(ILog logger) 
    { 
     this.logger=logger; 
    } 
     public void Execute(IJobExecutionContext context) 
     { 

      var thread = new Thread(()=> 
      { 
       try 
       { 
        this.ExecuteJob(context); 
       } 
       catch(Exception ex) 
       { 
        this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString()); 

       } 
      }); 

      thread.Start(); 
      this.currentThread = thread; 
      this.currentThread.Join(); 
     } 
     public abstract void ExecuteJob(IJobExecutionContext context); 

     public void Interrupt() 
     { 
      currentThread.Abort(); 
     } 
} 

每个作业都将执行JobExecute方法。

public class TestJob :JobBase 
{ 
    private ILog logger; 
    public TeJob(ILog logger):base(logger) 
    { 
    } 

    public override ExecuteJob(IJobExecutionContext context) 
    { 
    } 
} 

假设条件是,利用一些工厂创建工作

停止作业,你会调用方法scheduler.Interrupt(new JobKey(jobName));

+0

这看起来正是我所需要的。但是,每当我尝试中断一项工作时,我都会得到exceptoin'ThreadAbortException'。 – Schoof

+0

@Schoof这是正确的。如果你看一下'Thread.Abort()'的文档,你会发现它引发了一个'ThreadAbortException' https://msdn.microsoft.com/en-us/library/system.threading.thread.abort(v = vs.110).aspx –

0

我不知道为什么没有人提到了这一点,也许这是不可用问题提出的时间。

调度程序实例有一种称为关闭的方法。

SchedulerFactory factory = new StdSchedulerFactor(); 
Scheduler scheduler = factory.getScheduler(); 

以上用于启动工作像

scheduler.start(); 

使用标志或东西,知道什么时候该停止运行的工作。然后使用

scheduler.shutdown(); 

我如何实现我的要求:

if(flag==true) 
{ 
    scheduler.start(); 
    scheduler.scheduleJob(jobDetail, simpleTrigger); 
} 
else if(flag==false) 
{ 
    scheduler.shutdown(); 
} 

其中的JobDetail和simpleTrigger不言自明。

希望它有帮助。 :)

+2

这会杀死整个调度程序,而不是调度程序中的特定作业 – Kathir

+2

是的,是的。 如果调度程序只有一个作业。那么这种方法会很好地工作。 刚刚提出了一个建议。 –

相关问题