2012-10-26 31 views
9

Tôi nhớ rằng chúng ta không thể giết công việc hiện tại đang chạy Quartz Job nhưng chúng ta có thể ngắt và kiểm tra boolean ở bất cứ nơi nào là cần thiết cho dù chúng ta cần tiếp tục với các hoạt động tiếp theo hay không.Có thể giết một công việc Quartz hiện đang chạy không?

Ngay cả khi chúng tôi triển khai InterruptableJob và gọi scheduler.interrupt để làm gián đoạn Công việc, công việc hiện tại sẽ vẫn đang chạy trên máy chủ.

Ex:

  1. Một truy vấn SQL tên đã được kích hoạt bởi các công việc thông qua Hibernate mà phải mất một thời gian dài
  2. Một cuộc gọi đã được thực hiện cho một máy chủ của bên thứ ba mà máy chủ của bên thứ ba phải mất một chặng đường dài thời gian để đáp ứng

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

Ai đó có thể sửa chữa sự hiểu biết của tôi và giải thích cho tôi cách chúng ta có thể giết hoặc ngừng việc thực hiện "hiện tại"?

Cảm ơn, Kathir

Trả lời

2

Như bạn nói, không có cách nào để làm gián đoạn "tàn nhẫn" một công việc trong thạch anh, không phải trong JAVA.

Bạn có thể đóng gói logic của công việc của mình trong một Thread riêng biệt và chạy nó với ExecutorService.

Hãy xem ví dụ này: https://stackoverflow.com/a/2275596/1517816

Giả QuartzJob của bạn là class Test và di chuyển logic kinh doanh của bạn trong lớp Task.

Hy vọng nó giúp

+0

Tôi đồng ý rằng chúng tôi không thể giết chết công việc một cách dã man bằng Quartz, không phải trong JAVA. Ngoài ra, đồng ý rằng chúng tôi có thể đạt được như vậy thông qua ExecutorService. Trong sự tò mò của tôi, nó đặt ra thêm một câu hỏi tại sao Quartz không thực hiện ExecutorService để họ có thể cung cấp cho chúng ta một cách để giết công việc? Hoặc là có một kế hoạch tương lai trong các cải tiến Quartz. Cảm ơn bạn đã làm rõ và vui lòng cho tôi biết suy nghĩ của bạn. – Kathir

+0

Tại sao nó không thực hiện có lẽ vì nó đã được thiết kế để cung cấp một sự thay thế cho sự thiếu hụt này trong jvm. Nó hoạt động với các jvms cũ và nếu chúng triển khai ExecutorService, thạch anh sẽ được liên kết với một dự án jvm và force gần đây để di chuyển – poussma

+0

Có lẽ chúng có thể hỗ trợ thêm hoặc mở rộng thông qua một cấu hình. Bằng cách đó, họ có thể đạt được khả năng tương thích xuống cũng như mới ... tôi có thiếu sót gì không? Dù sao thì nhờ thời gian và giải thích của bạn ... – Kathir

6

bạn có thể tạo lớp trừu tượng mới có tên gọi JobBase ví dụ mà thực hiện giao diện IJob và chèn phương pháp trừu tượng: public abstract void ExecuteJob(IJobExecutionContext context);

On JobBase bạn có thể thực hiện phương pháp Execute như thế này

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

Mỗi công việc sẽ thực hiện phương thức JobExecute.

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

    public override ExecuteJob(IJobExecutionContext context) 
    { 
    } 
} 

Giả rằng việc sử dụng một số nhà máy để tạo một Job

Đối Dừng một công việc bạn sẽ gọi phương thức scheduler.Interrupt(new JobKey(jobName));

+0

Điều này trông giống như chính xác những gì tôi cần. Nhưng bất cứ khi nào tôi cố gắng làm gián đoạn công việc, tôi nhận được ngoại lệ 'ThreadAbortException'. – Schoof

+0

@Schoof Đúng vậy. Nếu bạn nhìn vào tài liệu của 'Thread.Abort()', bạn sẽ thấy nó tạo ra một 'ThreadAbortException' https://msdn.microsoft.com/en-us/library/system.threading.thread.abort(v = vs.110) .aspx –

0

Tôi không biết tại sao không ai nhắc đến điều này, hoặc có lẽ đây không phải là có sẵn tại thời điểm câu hỏi được hỏi.

Có một phương pháp được gọi là tắt máy cho phiên bản Trình lập lịch biểu.

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

Trên đây được sử dụng để bắt đầu một công việc như

scheduler.start(); 

Sử dụng một lá cờ hoặc một cái gì đó để biết khi nào phải ngừng công việc từ chạy.Sau đó sử dụng

scheduler.shutdown(); 

Làm thế nào tôi thực hiện yêu cầu của tôi:

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

đâu jobDetail và simpleTrigger là tự giải thích.

Hy vọng điều đó sẽ hữu ích. :)

+2

Thao tác này sẽ xóa toàn bộ trình lập lịch thay vì một công việc cụ thể trong bộ lập lịch – Kathir

+2

Có, có. Nếu trình lên lịch chỉ có một công việc. Sau đó, phương pháp này sẽ hoạt động hoàn hảo. Chỉ cần đưa ra một gợi ý. –

Các vấn đề liên quan