Quartz之InterruptableJob

问题1 由于业务需要,停止Quartz中正在执行的任务 
Quartz:你的任务类只需要实现InterruptableJob类就可以了 
只要实现一个方法:interrupt(),在这个方法中进行标记的改变,在执行中进行这个标记判断 
就可实现中断任务了,另外在调度器上调用方法:sched.interrupt(job.getKey());
 
在查看Quartz文档中已经有说明了,如下: 

Java代码    收藏代码
  1. The interface to be implemented by Jobs that provide a mechanism for having their execution interrupted. It is NOT a requirement for jobs to implement this interface - in fact, for most people, none of their jobs will.  
  2.   
  3. Interrupting a Job is very analogous in concept and challenge to normal interruption of a Thread in Java.  
  4.   
  5. The means of actually interrupting the Job must be implemented within the Job itself (the interrupt() method of this interface is simply a means for the scheduler to inform the Job that a request has been made for it to be interrupted). The mechanism that your jobs use to interrupt themselves might vary between implementations. However the principle idea in any implementation should be to have the body of the job's execute(..) periodically check some flag to see if an interruption has been requested, and if the flag is set, somehow abort the performance of the rest of the job's work. An example of interrupting a job can be found in the java source for the class org.quartz.examples.DumbInterruptableJob. It is legal to use some combination of wait() and notify() synchronization within interrupt() and execute(..) in order to have the interrupt() method block until the execute(..) signals that it has noticed the set flag.  
  6.   
  7. If the Job performs some form of blocking I/O or similar functions, you may want to consider having the Job.execute(..) method store a reference to the calling Thread as a member variable. Then the Implementation of this interfaces interrupt() method can call interrupt() on that Thread. Before attempting this, make sure that you fully understand what java.lang.Thread.interrupt() does and doesn't do. Also make sure that you clear the Job's member reference to the Thread when the execute(..) method exits (preferably in a finally block.  
  8.   
  9. See Example 7 (org.quartz.examples.example7.DumbInterruptableJob) for a simple implementation demonstration  


具体代码如下: 
DumbInterruptableJob.java 

Java代码    收藏代码
  1. package org.quartz.examples.example7;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8. import org.quartz.InterruptableJob;  
  9. import org.quartz.JobExecutionContext;  
  10. import org.quartz.JobExecutionException;  
  11. import org.quartz.JobKey;  
  12. import org.quartz.UnableToInterruptJobException;  
  13.   
  14.   
  15. /** 
  16.  * @author <a href="mailto:[email protected]">Chris Bonham</a> 
  17.  * @author Bill Kratzer 
  18.  */  
  19. public class DumbInterruptableJob implements InterruptableJob {  
  20.       
  21.     // logging services  
  22.     private static Logger _log = LoggerFactory.getLogger(DumbInterruptableJob.class);  
  23.       
  24.     // has the job been interrupted?  
  25.     private boolean _interrupted = false;  
  26.   
  27.     // job name   
  28.     private JobKey _jobKey = null;  
  29.       
  30.     private static int counts = 0;        
  31.       
  32.    
  33.     public DumbInterruptableJob() {  
  34.     }  
  35.   
  36.   
  37.     public void execute(JobExecutionContext context)  
  38.         throws JobExecutionException {  
  39.   
  40.         _jobKey = context.getJobDetail().getKey();  
  41.         _log.error("任务Key: " + _jobKey + " 执行时间: " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));  
  42.   
  43.         try {  
  44.            
  45.             for (int i = 0; i < 4; i++) {  
  46.                 try {  
  47.                     Thread.sleep(1000L);  
  48.                 } catch (Exception ignore) {  
  49.                     ignore.printStackTrace();  
  50.                 }                  
  51.                 
  52.                 if(_interrupted) {  
  53.                     _log.error("被外界因素停止了这个任务key: " + _jobKey + ",当前执行次数: " + counts);  
  54.                     return// could also choose to throw a JobExecutionException   
  55.                              // if that made for sense based on the particular    
  56.                              // job's responsibilities/behaviors  
  57.                 }  
  58.                 //执行业务方法  
  59.                 userManager();  
  60.             }  
  61.               
  62.         } finally {  
  63.             _log.error("任务执行完成key: " + _jobKey + " 执行时间: " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));  
  64.         }  
  65.     }  
  66.       
  67.     private void userManager() {  
  68.         _log.error("正在执行插入数据库的操作,次数: " + (++counts));         
  69.     }  
  70.   
  71.     public void interrupt() throws UnableToInterruptJobException {  
  72.         _log.info("外界正在调用调度器停止这个任务key: " + _jobKey);  
  73.         _interrupted = true;  
  74.     }  
  75. }  


InterruptExample.java 

Java代码    收藏代码
  1. package org.quartz.examples.example7;  
  2.   
  3. import static org.quartz.JobBuilder.newJob;  
  4. import static org.quartz.SimpleScheduleBuilder.simpleSchedule;  
  5. import static org.quartz.TriggerBuilder.newTrigger;  
  6. import static org.quartz.DateBuilder.*;  
  7.   
  8. import java.util.Date;  
  9.   
  10. import org.quartz.JobDetail;  
  11. import org.quartz.Scheduler;  
  12. import org.quartz.SchedulerFactory;  
  13. import org.quartz.SchedulerMetaData;  
  14. import org.quartz.SimpleTrigger;  
  15. import org.quartz.impl.StdSchedulerFactory;  
  16. import org.slf4j.Logger;  
  17. import org.slf4j.LoggerFactory;  
  18.   
  19.   
  20. public class InterruptExample {  
  21.   
  22.     public void run() throws Exception {  
  23.         final Logger log = LoggerFactory.getLogger(InterruptExample.class);  
  24.        
  25.         SchedulerFactory sf = new StdSchedulerFactory();  
  26.         Scheduler sched = sf.getScheduler();  
  27.          
  28.         Date startTime = nextGivenSecondDate(null15);  
  29.   
  30.         JobDetail job = newJob(DumbInterruptableJob.class)  
  31.             .withIdentity("interruptableJob1""group1")  
  32.             .build();  
  33.           
  34.         //当前时间15秒后,每间隔5秒执行一次任务  
  35.         SimpleTrigger trigger = newTrigger()   
  36.             .withIdentity("trigger1""group1")  
  37.             .startAt(startTime)  
  38.             .withSchedule(simpleSchedule()  
  39.                     .withIntervalInSeconds(5)  
  40.                     .repeatForever())  
  41.             .build();  
  42.   
  43.         Date ft = sched.scheduleJob(job, trigger);  
  44.         log.error(job.getKey() + " will run at: " + ft + " and repeat: "  
  45.                 + trigger.getRepeatCount() + " times, every "  
  46.                 + trigger.getRepeatInterval() / 1000 + " seconds");  
  47.   
  48.         sched.start();  
  49.          
  50.         for(int i=0; i < 10; i++) {  
  51.             try {  
  52.                 Thread.sleep(7000L);                  
  53.                 sched.interrupt(job.getKey());  
  54.             } catch (Exception e) {  
  55.             }  
  56.         }          
  57.        
  58.         sched.shutdown(true);  
  59.         
  60.         SchedulerMetaData metaData = sched.getMetaData();  
  61.         log.error("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");  
  62.   
  63.     }  
  64.   
  65.     public static void main(String[] args) throws Exception {  
  66.   
  67.         InterruptExample example = new InterruptExample();  
  68.         example.run();  
  69.     }  
  70. }  

猜你喜欢

转载自zxb1985.iteye.com/blog/1841409