Quartz之JobDataMap,PersistJobDataAfterExecution,DisallowConcurrentExecution

参考资料
http://stackoverflow.com/questions/1636556/ensure-that-spring-quartz-job-execution-doesnt-overlap

JobDataMap:任务数据传输对象,并且以Map形式存储,它重载了:putAsString()方法,如下图:
Quartz之JobDataMap,PersistJobDataAfterExecution,DisallowConcurrentExecution,类说明如下:
JobDataMap instances are stored once when the Job is added to a scheduler. They are also re-persisted after every execution of StatefulJob instances.
JobDataMap instances can also be stored with a Trigger. This can be useful in the case where you have a Job that is stored in the scheduler for regular/repeated use by multiple Triggers, yet with each independent triggering, you want to supply the Job with different data inputs.
The JobExecutionContext passed to a Job at execution time also contains a convenience JobDataMap that is the result of merging the contents of the trigger's JobDataMap (if any) over the Job's JobDataMap (if any). 

它继承了父类:StringKeyDirtyFlagMap,它重载了方法:put()方法,如下图:
Quartz之JobDataMap,PersistJobDataAfterExecution,DisallowConcurrentExecution,类说明如下:
An implementation of Map that wraps another Map and flags itself 'dirty' when it is modified, enforces that all keys are Strings.
All allowsTransientData flag related methods are deprecated as of version 1.6. 
,可以说:JobDataMap这个对象可以向任务传递任何对象.
以下这个示例用到了Quartz的二个注解,其实它推荐我们使用这二个注解.在这篇文章中作了如下说明:
Quartz之JobDataMap,PersistJobDataAfterExecution,DisallowConcurrentExecution
以下这二个注解是我根据字面上的意思理解的呀
@PersistJobDataAfterExecution:保存在JobDataMap传递的参数,当你要一个计数器的时候,详情可参见以下这个例子.
@DisallowConcurrentExecution:保证多个任务间不会同时执行.所以在多任务执行时最好加上

具体参见代码(你可反复测试效果就知道了 ),详情请参见注解
ColorJob.java
package org.quartz.examples.example4;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class ColorJob implements Job {

    private static Logger _log = LoggerFactory.getLogger(ColorJob.class);    
   
    public static final String FAVORITE_COLOR = "favorite color";
    public static final String EXECUTION_COUNT = "count";    
   
    //这个属性如不是static,那么每次都要实例这个任务类,始终打印为: 1
    private static  int _counter = 1;
   
    public ColorJob() {
    }  
    public void execute(JobExecutionContext context)
        throws JobExecutionException {

      
        JobKey jobKey = context.getJobDetail().getKey();        
       
        JobDataMap data = context.getJobDetail().getJobDataMap();
        String favoriteColor = data.getString(FAVORITE_COLOR);
        int count = data.getInt(EXECUTION_COUNT);
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        
        
        _log.error("任务Key: " + jobKey + " ,执行时间:  " + sdf.format(new Date()) + "\n" +
            "  传递参数(favorite color): " + favoriteColor + "\n" + 
            "  传递参数(count):  " + count + "\n" + 
            "  ColorJob静态变量值: " + _counter);
     
        count++;
        data.put(EXECUTION_COUNT, count);        
      
        _counter++;
    }
}

JobStateExample .java
package org.quartz.examples.example4;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.DateBuilder.*;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JobStateExample {

    public void run() throws Exception {
    	
        Logger log = LoggerFactory.getLogger(JobStateExample.class);
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();

        //在当前时间10秒后运行
        Date startTime = nextGivenSecondDate(null, 10);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        
       

        //通过过JobDetail封装ColorJob,同时指定Job在Scheduler中所属组及名称,这里,组名为group1,而名称为job1。
        JobDetail job1 = newJob(ColorJob.class)
            .withIdentity("job1", "group1")
            .build();
    
       // 创建一个SimpleTrigger实例,指定该Trigger在Scheduler中所属组及名称。
	   // 接着设置调度的时间规则.当前时间10秒后运行,每10秒运行一次,共运行4次
        SimpleTrigger trigger1 = newTrigger() 
            .withIdentity("trigger1", "group1")
            .startAt(startTime)
            .withSchedule(simpleSchedule()
                    .withIntervalInSeconds(10)
                    .withRepeatCount(4))
            .build();
        
        //将参数传递入任务的数据Map中
        job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Green");
        job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);
        
        //注册并进行调度
        Date scheduleTime1 = sched.scheduleJob(job1, trigger1);
        
        log.error("任务key: "+job1.getKey() + ",执行运行时间: " + sdf.format(scheduleTime1) +  
                ",触发器重复执行次数: " + trigger1.getRepeatCount() + 
                ",触发器执行时间: " + trigger1.getRepeatInterval() / 1000 + " seconds");
        

        //第二个任务
        JobDetail job2 = newJob(ColorJob.class)
            .withIdentity("job2", "group1")
            .build();
    
        SimpleTrigger trigger2 = newTrigger() 
            .withIdentity("trigger2", "group1")
            .startAt(startTime)
            .withSchedule(simpleSchedule()
                    .withIntervalInSeconds(10)
                    .withRepeatCount(4))
            .build();

        //传递数据
        job2.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Red");
        job2.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1);
        
       
        Date scheduleTime2 = sched.scheduleJob(job2, trigger2);
        
        log.error("第二个任务key: "+job2.getKey().toString() + ",执行运行时间: " + sdf.format(scheduleTime2) +  
                ",触发器重复执行次数: " + trigger2.getRepeatCount() + 
                ",触发器执行时间: " + trigger2.getRepeatInterval() / 1000 + " seconds");


        //调度器启动
        sched.start();

        try {          
            Thread.sleep(60L * 1000L);          
        } catch (Exception e) {        	
        }

      //调度器停止
        sched.shutdown(true);
        
        SchedulerMetaData metaData = sched.getMetaData();
        log.error("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");

    }

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

        JobStateExample example = new JobStateExample();
        example.run();
    }
}

输出结果如下:
[ERROR] 2011-08-10 02:56:44.453 下午 main [org.quartz.examples.example4.JobStateExample]
任务key: group1.job1,执行运行时间: 2011-08-10 02:56:50,触发器重复执行次数: 4,触发器执行时间: 10 seconds

[ERROR] 2011-08-10 02:56:44.453 下午 main [org.quartz.examples.example4.JobStateExample]
第二个任务key: group1.job2,执行运行时间: 2011-08-10 02:56:50,触发器重复执行次数: 4,触发器执行时间: 10 seconds

[ERROR] 2011-08-10 02:56:50.015 下午 DefaultQuartzScheduler_Worker-1 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job1 ,执行时间:  2011-08-10 02:56:50
  传递参数(favorite color): Green
  传递参数(count):  1
  ColorJob静态变量值: 1

[ERROR] 2011-08-10 02:56:50.015 下午 DefaultQuartzScheduler_Worker-2 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job2 ,执行时间:  2011-08-10 02:56:50
  传递参数(favorite color): Red
  传递参数(count):  1
  ColorJob静态变量值: 1

[ERROR] 2011-08-10 02:57:00.000 下午 DefaultQuartzScheduler_Worker-4 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job2 ,执行时间:  2011-08-10 02:57:00
  传递参数(favorite color): Red
  传递参数(count):  2
  ColorJob静态变量值: 3

[ERROR] 2011-08-10 02:57:00.000 下午 DefaultQuartzScheduler_Worker-3 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job1 ,执行时间:  2011-08-10 02:57:00
  传递参数(favorite color): Green
  传递参数(count):  2
  ColorJob静态变量值: 3

[ERROR] 2011-08-10 02:57:10.000 下午 DefaultQuartzScheduler_Worker-5 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job1 ,执行时间:  2011-08-10 02:57:10
  传递参数(favorite color): Green
  传递参数(count):  3
  ColorJob静态变量值: 5

[ERROR] 2011-08-10 02:57:10.000 下午 DefaultQuartzScheduler_Worker-6 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job2 ,执行时间:  2011-08-10 02:57:10
  传递参数(favorite color): Red
  传递参数(count):  3
  ColorJob静态变量值: 5

[ERROR] 2011-08-10 02:57:20.000 下午 DefaultQuartzScheduler_Worker-7 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job1 ,执行时间:  2011-08-10 02:57:20
  传递参数(favorite color): Green
  传递参数(count):  4
  ColorJob静态变量值: 7

[ERROR] 2011-08-10 02:57:20.000 下午 DefaultQuartzScheduler_Worker-8 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job2 ,执行时间:  2011-08-10 02:57:20
  传递参数(favorite color): Red
  传递参数(count):  4
  ColorJob静态变量值: 7

[ERROR] 2011-08-10 02:57:30.000 下午 DefaultQuartzScheduler_Worker-9 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job1 ,执行时间:  2011-08-10 02:57:30
  传递参数(favorite color): Green
  传递参数(count):  5
  ColorJob静态变量值: 9

[ERROR] 2011-08-10 02:57:30.000 下午 DefaultQuartzScheduler_Worker-10 [org.quartz.examples.example4.ColorJob]
任务Key: group1.job2 ,执行时间:  2011-08-10 02:57:30
  传递参数(favorite color): Red
  传递参数(count):  5
  ColorJob静态变量值: 10

[ERROR] 2011-08-10 02:57:44.453 下午 main [org.quartz.examples.example4.JobStateExample]
Executed 10 jobs.

src下的log4j的日志级别设置成了error
log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <appender name="default" class="org.apache.log4j.ConsoleAppender">
    <param name="target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="[%p] %d{yyyy-MM-dd hh:mm:ss.SSS aa} %t [%c]%n%m%n%n"/>
    </layout>
  </appender>

 <logger name="org.quartz">
   <level value="error" />
 </logger>

  <root>
    <level value="info" />
    <appender-ref ref="default" />
  </root>  
</log4j:configuration>

你可能感兴趣的:(java,log4j,quartz)