Quartz框架(一)—Quartz的基本配置
Quartz框架(二)—jobstore数据库表字段详解
Quartz框架(三)—任务的并行/串行执行
Quartz框架(四)—misfire处理机制
Quartz框架(五)— 有状态的job和无状态job
Quartz框架(六)— Trigger状态转换
Quartz框架(七)— Quartz集群原理
Quartz框架(八)— Quartz实现异步通知
Quartz框架(九)— 动态操作Quartz定时任务
Quartz框架(十)监听
Job中有一个StatefulJob子接口,代表着有状态的任务,该接口是一个没有方法的标签接口,其目的就是让Quartz知道任务的类型,以便采用不同的执行方案。
/*
*
* @deprecated use DisallowConcurrentExecution and/or PersistJobDataAfterExecution annotations instead.
*
* @author James House
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public interface StatefulJob extends Job {
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
}
正如原码中描述:use DisallowConcurrentExecution and/or PersistJobDataAfterExecution annotations instead.
该接口已过时,但是可以使用上面的注解代替。
- @DisallowConcurrentExecution 不允许并发执行,即JOB为串行执行。
- @PersistJobDataAfterExecution 在执行后将JobData持久化。
无状态任务在执行时,拥有自己的JobDataMap拷贝,对JobData的更改不会影响下次的执行。而有状态任务共享同一个JobDataMap实例,每次任务执行对JobDataMap所做的更改都会保存下来,后面的执行可以看到这个更改。也就是每次执行任务后都会对后面的执行发生影响。
正因为这个原因,无状态的Job可以并发执行,而有状态的StatefulJob不能并发执行,这意味着如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度,因此除非必要,应该尽量使用无状态的Job。
如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。
Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。
案例测试:
1. 有状态的Job
@Component
public class TestJob2 extends CustomQuartzJobBean implements StatefulJob {
private Logger logger = LoggerFactory.getLogger(TestJob2.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String value = jobDataMap.getString("key");
logger.info("value的值:"+value);
//设置jobData的值
jobDataMap.put("key",value + "哈哈");
logger.info("【数据库配置定时】-【结束】");
}
}
执行结果:
2019-07-08 14:32:20,572 INFO [6105] [clusteredScheduler_Worker-6] [] (TestJob2.java:30): value的值:这是一个
2019-07-08 14:32:20,573 INFO [6106] [clusteredScheduler_Worker-6] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2019-07-08 14:32:25,020 INFO [10553] [clusteredScheduler_Worker-7] [] (TestJob2.java:30): value的值:这是一个哈哈
2019-07-08 14:32:25,021 INFO [10554] [clusteredScheduler_Worker-7] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2019-07-08 14:32:30,013 INFO [15546] [clusteredScheduler_Worker-8] [] (TestJob2.java:30): value的值:这是一个哈哈哈哈
2019-07-08 14:32:30,013 INFO [15546] [clusteredScheduler_Worker-8] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2019-07-08 14:32:35,017 INFO [20550] [clusteredScheduler_Worker-9] [] (TestJob2.java:30): value的值:这是一个哈哈哈哈哈哈
2019-07-08 14:32:35,018 INFO [20551] [clusteredScheduler_Worker-9] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2019-07-08 14:32:40,015 INFO [25548] [clusteredScheduler_Worker-10] [] (TestJob2.java:30): value的值:这是一个哈哈哈哈哈哈哈哈
2019-07-08 14:32:40,015 INFO [25548] [clusteredScheduler_Worker-10] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2019-07-08 14:32:45,016 INFO [30549] [clusteredScheduler_Worker-1] [] (TestJob2.java:30): value的值:这是一个哈哈哈哈哈哈哈哈哈哈
2019-07-08 14:32:45,016 INFO [30549] [clusteredScheduler_Worker-1] [] (TestJob2.java:33): 【数据库配置定时】-【结束】
2. 无状态的Job
@Component
public class TestJob2 extends CustomQuartzJobBean {
private Logger logger = LoggerFactory.getLogger(TestJob2.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String value = jobDataMap.getString("key");
logger.info("value的值:"+value);
//设置jobData的值
jobDataMap.put("key",value + "哈哈");
logger.info("【数据库配置定时】-【结束】");
}
}
执行结果:
2019-07-08 15:05:25,026 INFO [8174] [clusteredScheduler_Worker-2] [] (TestJob2.java:23): value的值:这是一个
2019-07-08 15:05:25,026 INFO [8174] [clusteredScheduler_Worker-2] [] (TestJob2.java:27): 【数据库配置定时】-【结束】
2019-07-08 15:05:30,017 INFO [13165] [clusteredScheduler_Worker-3] [] (TestJob2.java:23): value的值:这是一个
2019-07-08 15:05:30,017 INFO [13165] [clusteredScheduler_Worker-3] [] (TestJob2.java:27): 【数据库配置定时】-【结束】
2019-07-08 15:05:35,020 INFO [18168] [clusteredScheduler_Worker-4] [] (TestJob2.java:23): value的值:这是一个
2019-07-08 15:05:35,021 INFO [18169] [clusteredScheduler_Worker-4] [] (TestJob2.java:27): 【数据库配置定时】-【结束】
2019-07-08 15:05:40,018 INFO [23166] [clusteredScheduler_Worker-5] [] (TestJob2.java:23): value的值:这是一个
2019-07-08 15:05:40,019 INFO [23167] [clusteredScheduler_Worker-5] [] (TestJob2.java:27): 【数据库配置定时】-【结束】