Spring Boot定时任务spring-boot-starter-quartz通过@DisallowConcurrentExecution禁止任务并发执行

Spring Boot定时任务spring-boot-starter-quartz配置运行及测试这篇文章中我们简单介绍了Spring Boot中如何实现定时任务,但是有个问题,当任务的执行时长超过定时任务触发的间隔时,就会导致两个或多个任务并发在执行,如果我们不希望定时任务并发执行可以通过@DisallowConcurrentExecution注解来禁止并发。

下面通过简单的代码来演示定时任务并发和串行的情况,关于定时任务的配置先看这篇文章Spring Boot定时任务spring-boot-starter-quartz配置运行及测试

配置

将定时任务间隔设置成3秒

@Configuration
public class CustomizeScheduleConfigTask {
    /**
     * 定时任务
     * @return
     */
    @Bean
    public JobDetail testJobDetail() {
        return JobBuilder.newJob(TestJobBean.class)
                .withIdentity("testJobDetail")
                .storeDurably()
                .build();
    }
 
    /**
     * 触发器,每间隔一段时间触发定时任务
     * @param jobDetail 具体执行的定时任务
     * @return
     */
    @Bean
    public Trigger testJobTrigger(@Qualifier("testJobDetail") JobDetail jobDetail) {
        ScheduleBuilder scheduleBuilder = SimpleScheduleBuilder
                .simpleSchedule()
                .withIntervalInSeconds(3) // 定时任务间隔时间
                .repeatForever(); // 触发器无限循环触发
        return TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                .withIdentity("testJobTrigger")
                .withSchedule(scheduleBuilder)
                .build();
    }
}

并发

定时任务默认就是并发的

我们通过Thread.sleep()让任务执行时间为6秒,超过定时任务触发间隔的3秒,这样就可以观察到并发

@Service
public class TestJobBean extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        System.out.println("TestJobBean 开始:::" + Thread.currentThread().getName() + ":::" + SimpleDateFormat.getDateTimeInstance().format(new Date()));
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("TestJobBean 结束:::" + Thread.currentThread().getName() + ":::" + SimpleDateFormat.getDateTimeInstance().format(new Date()));
    }
}

 运行项目,log如下

我们只需看quartzScheduler_Worker-2这个任务的开始和结束之间,quartzScheduler_Worker-3和quartzScheduler_Worker-4这两个任务也同时在执行,并未等quartzScheduler_Worker-2任务结束后才执行,说明该定时任务是并发的

TestJobBean 开始:::quartzScheduler_Worker-2:::Aug 5, 2020 3:15:42 PM // quartzScheduler_Worker-2任务开始
TestJobBean 开始:::quartzScheduler_Worker-3:::Aug 5, 2020 3:15:43 PM
TestJobBean 开始:::quartzScheduler_Worker-4:::Aug 5, 2020 3:15:46 PM
TestJobBean 结束:::quartzScheduler_Worker-2:::Aug 5, 2020 3:15:48 PM // quartzScheduler_Worker-2任务结束
TestJobBean 开始:::quartzScheduler_Worker-5:::Aug 5, 2020 3:15:49 PM
TestJobBean 结束:::quartzScheduler_Worker-3:::Aug 5, 2020 3:15:49 PM
TestJobBean 开始:::quartzScheduler_Worker-6:::Aug 5, 2020 3:15:52 PM
TestJobBean 结束:::quartzScheduler_Worker-4:::Aug 5, 2020 3:15:52 PM
TestJobBean 结束:::quartzScheduler_Worker-5:::Aug 5, 2020 3:15:55 PM
TestJobBean 开始:::quartzScheduler_Worker-7:::Aug 5, 2020 3:15:55 PM
TestJobBean 开始:::quartzScheduler_Worker-8:::Aug 5, 2020 3:15:58 PM
TestJobBean 结束:::quartzScheduler_Worker-6:::Aug 5, 2020 3:15:58 PM
TestJobBean 开始:::quartzScheduler_Worker-10:::Aug 5, 2020 3:16:01 PM
TestJobBean 结束:::quartzScheduler_Worker-7:::Aug 5, 2020 3:16:01 PM
TestJobBean 开始:::quartzScheduler_Worker-1:::Aug 5, 2020 3:16:04 PM

串行(非并发)

在原来的定时任务上添加@DisallowConcurrentExecution注解就可以禁止并发

@DisallowConcurrentExecution // 禁止并发执行
@Service
public class TestJobBean extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        System.out.println("TestJobBean 开始:::" + Thread.currentThread().getName() + ":::" + SimpleDateFormat.getDateTimeInstance().format(new Date()));
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("TestJobBean 结束:::" + Thread.currentThread().getName() + ":::" + SimpleDateFormat.getDateTimeInstance().format(new Date()));
    }
}

运行项目,打印log如下

可以看到log非常工整,都是一个任务结束后才开始下一个任务,说明该定时任务是串行的

TestJobBean 开始:::quartzScheduler_Worker-2:::Aug 5, 2020 3:12:14 PM
TestJobBean 结束:::quartzScheduler_Worker-2:::Aug 5, 2020 3:12:20 PM
TestJobBean 开始:::quartzScheduler_Worker-3:::Aug 5, 2020 3:12:20 PM
TestJobBean 结束:::quartzScheduler_Worker-3:::Aug 5, 2020 3:12:26 PM
TestJobBean 开始:::quartzScheduler_Worker-4:::Aug 5, 2020 3:12:27 PM
TestJobBean 结束:::quartzScheduler_Worker-4:::Aug 5, 2020 3:12:33 PM
TestJobBean 开始:::quartzScheduler_Worker-6:::Aug 5, 2020 3:12:33 PM
TestJobBean 结束:::quartzScheduler_Worker-6:::Aug 5, 2020 3:12:39 PM
TestJobBean 开始:::quartzScheduler_Worker-7:::Aug 5, 2020 3:12:42 PM
TestJobBean 结束:::quartzScheduler_Worker-7:::Aug 5, 2020 3:12:48 PM
TestJobBean 开始:::quartzScheduler_Worker-8:::Aug 5, 2020 3:12:48 PM
TestJobBean 结束:::quartzScheduler_Worker-8:::Aug 5, 2020 3:12:54 PM
TestJobBean 开始:::quartzScheduler_Worker-10:::Aug 5, 2020 3:12:57 PM
TestJobBean 结束:::quartzScheduler_Worker-10:::Aug 5, 2020 3:13:03 PM
TestJobBean 开始:::quartzScheduler_Worker-1:::Aug 5, 2020 3:13:03 PM
TestJobBean 结束:::quartzScheduler_Worker-1:::Aug 5, 2020 3:13:09 PM
TestJobBean 开始:::quartzScheduler_Worker-3:::Aug 5, 2020 3:13:12 PM
TestJobBean 结束:::quartzScheduler_Worker-3:::Aug 5, 2020 3:13:18 PM
TestJobBean 开始:::quartzScheduler_Worker-4:::Aug 5, 2020 3:13:18 PM
TestJobBean 结束:::quartzScheduler_Worker-4:::Aug 5, 2020 3:13:24 PM

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值