2012-10-26 123 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

是的,是的。 如果調度程序只有一個作業。那麼這種方法會很好地工作。 剛剛提出了一個建議。 –

相關問題