`

Quartz之JobDataMap,PersistJobDataAfterExecution,DisallowConcurrentExecution

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

JobDataMap:任务数据传输对象,并且以Map形式存储,它重载了:putAsString()方法,如下图:
,类说明如下:
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()方法,如下图:
,类说明如下:
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的二个注解,其实它推荐我们使用这二个注解.在这篇文章中作了如下说明:

以下这二个注解是我根据字面上的意思理解的呀
@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>
  • 大小: 18.4 KB
  • 大小: 9.6 KB
  • 大小: 86.1 KB
分享到:
评论

相关推荐

    java 任务分配样例3

    在本文中,我们将深入探讨如何使用`@PersistJobDataAfterExecution`和`@DisallowConcurrentExecution`注解来通过JobDataMap向Quartz 2调度的任务传递参数。 首先,`JobDataMap`是Quartz 2提供的一种机制,用于在...

    quartz-2.3.0-distribution.zip

    - 利用`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`注解控制Job的行为。 3. **quartz.sql和sql.txt** - `quartz.sql`:这是Quartz用于创建其内部工作表的SQL脚本,这些表存储了Job、Trigger...

    Quartz使用小结

    3. **申明式调度** - 通过使用`@DisallowConcurrentExecution`和`@PersistJobDataAfterExecution`注解,可以在Job类上声明执行行为。同时,可以使用`@Scheduled`注解在方法上直接定义调度。 4. **使用`quartz....

    spring-boot集成quartz实现动态任务管理,支持集群

    在Spring Boot中,你可以通过实现`org.springframework.scheduling.quartz.JobDetailBean`并使用`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`注解来创建可重入或持久化的Job类。例如: ```...

    quartz定时程序 java

    开发者需要创建Job的实现类,并通过`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`注解来定义其并发行为和数据持久化需求。 - **Trigger**:Trigger则定义了Job的执行时间。Quartz提供了多种...

    quartzdemo

    - 使用`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`注解,控制Job实例的并发执行策略和数据持久化。 3. **Trigger的配置**: - **CronTrigger**:使用cron表达式定义执行时间,例如"0 0/5 *...

    Quartz-demo

    这包括使用`@DisallowConcurrentExecution`和`@PersistJobDataAfterExecution`注解来控制Job的行为,以及使用`@Scheduled`注解来声明基于Cron的定时任务。 总结起来,"Quartz-demo"是一个实践Quartz任务调度的实例...

    基于Spring的Quartz Demo

    - Spring为Quartz提供了良好的整合,允许你直接在Spring Bean中定义Job,通过`@Component`注解并使用`@DisallowConcurrentExecution`和`@PersistJobDataAfterExecution`注解。 - 可以使用`@Scheduled`注解来创建...

    Quartz

    在实际应用中,Quartz可以与其他框架或技术结合,例如Spring框架中的`@DisallowConcurrentExecution`和`@PersistJobDataAfterExecution`注解,可以控制Job的并发执行和数据持久化。通过这些特性,开发者可以构建出...

    quartz_annotation 例子

    2. **@PersistJobDataAfterExecution**: 这个注解表示在Job执行完成后,更新的JobDataMap数据应当持久化。这意味着在下次执行时,Job可以访问到上次执行时设置的数据。 3. **@DisallowConcurrentExecution** 和 **@...

    quartztool.rar QUARTZ封装

    5. **JobDataMap**:存储 Job 执行时所需的数据,可以在 Job 中通过 `@DisallowConcurrentExecution` 或 `@PersistJobDataAfterExecution` 注解控制并发行为。 通过阅读 `src` 中的源代码,你可以了解到作者是如何...

    Spring中使用Quartz(二)

    - 使用`@Component`注解定义Job类,然后通过`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`控制Job的行为。 - 使用`@Configuration`类创建bean,通过`SchedulerFactoryBean`的`addJob`和`...

    Quartz调度框架预研.docx

    使用 @DisallowConcurrentExecution 注解可以确保同一时间仅有一个任务实例在执行,而 @PersistJobDataAfterExecution 注解会在任务成功执行后更新 JobDataMap,使下次执行时能获取最新的数据。这两种注解都作用于 ...

    基于Spring的Quartz动态定时任务增删改查源码.rar

    4. **Spring整合Quartz**: 在Spring中,我们可以使用`@Component`注解声明Job类,并通过`@DisallowConcurrentExecution`或`@PersistJobDataAfterExecution`控制Job的行为。通过Spring的`SchedulerFactoryBean`,我们...

    Quarz相关资料.zip

    - 通过`@DisallowConcurrentExecution`和`@PersistJobDataAfterExecution`注解控制Job的行为。 7. **实战应用** - 定时发送邮件或短信服务。 - 数据库定时清理、备份任务。 - 日常业务统计报告的自动化生成。 ...

Global site tag (gtag.js) - Google Analytics