@DisallowConcurrentExecution 注解

Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行, 如果定时任执行太长,会长时间占用资源,导致其它任务堵塞。

在Spring中这时需要设置concurrent的值为false, 禁止并发执行。

 <property name="concurrent" value="true" />

当不使用spring的时候就需要在Job的实现类上加@DisallowConcurrentExecution的注释

@DisallowConcurrentExecution 禁止并发执行多个相同定义的JobDetail, 这个注解是加在Job类上的, 但意思并不是不能同时执行多个Job, 而是不能并发执行同一个Job Definition(由JobDetail定义),但是可以同时执行多个不同的JobDetail, 也就是说一个JobKey对应的JobDetail实例不会进行并发执行,举例说明,我们有一个Job类,叫做QuartzJob,QuartzJob1,QuartzJob2他们都是实现了Job接口,并在这些类上加了这个注解@DisallowConcurrentExecution, 然后在这个Job上定义了很多个JobDetail, QuartzJobJobDetail,QuartzJob1JobDetail,QuartzJob2JobDetail,那么当scheduler启动时, 不会并发执行多个QuartzJobJobDetail或者QuartzJob1JobDetail以及QuartzJob2JobDetail,而是QuartzJob类下QuartzJobJobDetail的任务调度同步执行,其它几个(QuartzJob1JobDetail,QuartzJob2JobDetail的任务调度下的)一样,但是可以同时执行QuartzJobJobDetail,QuartzJob1JobDetail,QuartzJob2JobDetail

  • @PersistJobDataAfterExecution 同样, 也是加在Job上,表示当正常执行完Job后, JobDataMap中的数据应该被改动, 以被下一次调用时用。(注意:@PersistJobDataAfterExecution是持久化JobDetail中的JobDataMap,对Trigger中的JobDataMap无效)
  • 当使用@PersistJobDataAfterExecution 注解时, 为了避免并发时, 存储数据造成混乱, 强烈建议把@DisallowConcurrentExecution注解也加上。

@DisallowConcurrentExecution

  • 此标记用在实现Job的类上面,意思是不允许并发执行,按照我之前的理解是 不允许调度框架在同一时刻调用Job类,后来经过测试发现并不是这样,而是Job(任务)的执行时间(比如需要10秒)大于任务的时间间隔【Interval(5秒)】,那么默认情况下,调度框架为了能让 任务按照我们预定的时间间隔执行,会马上启用新的线程执行任务。否则的话会等待任务执行完毕以后 再重新执行!(这样会导致任务的执行不是按照我们预先定义的时间间隔执行)
  • 测试代码,这是官方提供的例子。设定的时间间隔为3秒,但job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,否则会在3秒时再启用新的线程执行

代码如下:

/**
 * 该类将会被org.springframework.scheduling.quartz.SpringBeanJobFactory 实例化
 * 并使@Autowired 生效
 */
@Slf4j
@Setter
@DisallowConcurrentExecution
public class QuartzJob implements Job {

	@Autowired
	private ApplicationEventPublisher publisher;

	/**
	 * 任务调度参数key
	 */
	public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";

	private String dd;

	@Override
	@SneakyThrows
	public void execute(JobExecutionContext jobExecutionContext) {
		TreeNode o = (TreeNode) jobExecutionContext.getMergedJobDataMap().get(JOB_PARAM_KEY);
		JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
		JobDataMap jobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
		JobDataMap jobDataMap1 = jobExecutionContext.getJobDetail().getJobDataMap();

		System.out.println("QuartzJob  execute:" + SystemClock.nowDate());

		PerUsers user = new PerUsers();
		System.out.println("user hashCode: " + user.hashCode());
		System.out.println("user identityHashCode: " + System.identityHashCode(user));
		/**这个任务你不知道要执行多久,而我们这个多线程的特性间隔时间一到,
		 * 前面一个任务还没有执行完,那么它又会启动一个任务去执行,那如果时同一个实例的话就会存在并发问题
		 *
		 */
		System.out.println(System.identityHashCode(jobExecutionContext.getJobDetail()));
		System.out.println(System.identityHashCode(jobExecutionContext.getJobInstance()));
		//由此证明任务调度都是异步进行的 互不影响
		try {
			Thread.sleep(3000);
			System.out.println("user = ");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

}

结论:经过代码测试在没有加@DisallowConcurrentExecution注解之前是没有休眠3秒进行下一个任务它们互不干扰在QuartzJob 类加上@DisallowConcurrentExecution注解以后,中间会休息3秒以后执行下一个任务调度,由此可见,QuartzJob 类下的任务调度全部同步执行

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值