Spring Boot-定时任务

本文的核心内容:Spring Boot定时任务、Spring Boot定时任务线程池(多个任务同时执行)。


 

实现定时任务有很多方式,这里采用的是SpringTask的方式。

Spring Boot使用定时任务

1:Spring Boot项目启动类上加上 @EnableScheduling 注解  

 

2:自定义Job  @Scheduled(cron="")  //定时触发事件

 

Schecduled注解的参数,诸如:

        1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次

        2.zone表示执行时间的时区

        3.fixedDelay 和fixedDelayString 表示一个固定延迟时间执行,上个任务完成后,延迟多长时间执行

        4.fixedRate 和fixedRateString表示一个固定频率执行,上个任务开始后,多长时间后开始执行

        5.initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间

@Component
public class xxxJob{
        @Scheduled(cron="")
        public void xxxJob(){
                //业务逻辑
        }
}

其中Cron表达式可以设置任务执行的时间。具体如何书写不再详解,这不是这篇博客的主要内容。

 

到此,定时任务的简单使用就结束了。


 

SpringTask定时任务与多线程

 

下面介绍一些SpringTask定时任务的小知识。

1)假设你定义的任务1秒执行一次,然后让线程Sleep5秒,最后返回。观察打印的时间间隔

@Component
public class InitJob {

    @Scheduled(cron = "")
    public void initJob(){
        if (true){
             System.out.println(new Date());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return;
        }
    }
}

这个例子想说明,如果你定时任务执行时间超过了定时任务时间间隔,任务下次开始时间会顺延到下个可以执行的时间间隔。

换句话说,如果你的定时任务间隔2秒,而任务执行了3秒,它会在第5秒,也就是第二个任务间隔后执行下一次的定时任务。

 

2)如果你定义两个Job,在每个Job中打印当前线程的名字,你会发现你所定义的多个任务是由同一个线程执行。

换句话说,许多任务由一个线程,串行执行的。

源码可以找到答案

从ScheduledAnnotationBeanPostProcessor类开始一路找下去。在ScheduledTaskRegistrar(定时任务注册类)中的ScheduleTasks中又这样一段判断:默认使用的是单线程池。

if (this.taskScheduler == null) {
    this.localExecutor = Executors.newSingleThreadScheduledExecutor();
    this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}

 

我们只需用调用这个方法显式的设置一个ScheduledExecutorService就可以达到并发的效果了。我们要做的是实现SchedulingConfigurer接口,重写configureTasks方法就OK了。

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
/**
* 多线程执行定时任务
*/
@Configuration
//所有的定时任务都放在一个线程池中,定时任务启动时使用不同都线程。
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        //设定一个长度5的定时任务线程池
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }
}

这时,你在任务中打印当前线程名时,多个任务由多个线程同时执行。

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值