Spring Boot 的定时任务:

第一种:把参数配置到.properties文件中:

代码:


  1. package com.accord.task;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * 从配置文件加载任务信息
  8. * @author 王久印
  9. * 2018年3月1日
  10. */
  11. @Component
  12. public class ScheduledTask {
  13. private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
  14. //@Scheduled(fixedDelayString = "${jobs.fixedDelay}")
  15. @Scheduled(fixedDelayString = "2000")
  16. public void getTask1() {
  17. System.out.println("任务1,从配置文件加载任务信息,当前时间:" + dateFormat.format(new Date()));
  18. }
  19. @Scheduled(cron = "${jobs.cron}")
  20. public void getTask2() {
  21. System.out.println("任务2,从配置文件加载任务信息,当前时间:" + dateFormat.format(new Date()));
  22. }
  23. }

application.properties文件:


  1. jobs.fixedDelay=5000
  2. jobs.cron=0/5 * * * * ?

SpringBootCron2Application.java中:


  1. package com.accord;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.scheduling.annotation.EnableScheduling;
  5. @SpringBootApplication
  6. @EnableScheduling
  7. public class SpringBootCron2Application {
  8. public static void main(String[] args) {
  9. SpringApplication.run(SpringBootCron2Application.class, args);
  10. }
  11. }

注:@EnableScheduling  这个一定要加上;否则,不会定时启动任务!

@Scheduled中的参数说明:


  1. @Scheduled(fixedRate=2000):上一次开始执行时间点后2秒再次执行;
  2. @Scheduled(fixedDelay=2000):上一次执行完毕时间点后2秒再次执行;
  3. @Scheduled(initialDelay=1000, fixedDelay=2000):第一次延迟1秒执行,然后在上一次执行完毕时间点后2秒再次执行;
  4. @Scheduled(cron="* * * * * ?"):按cron规则执行。

在线Cron表达式生成器:http://cron.qqe2.com/

第二种定时任务:单线程和多线程

1、创建定时任务:


  1. package com.accord.task;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * 构建执行定时任务
  8. * @author 王久印
  9. * 2018年3月1日
  10. * TODO
  11. */
  12. @Component
  13. public class ScheduledTask2 {
  14. private Logger logger = LoggerFactory.getLogger(ScheduledTask2.class);
  15. private int fixedDelayCount = 1;
  16. private int fixedRateCount = 1;
  17. private int initialDelayCount = 1;
  18. private int cronCount = 1;
  19. @Scheduled(fixedDelay = 5000) //fixedDelay = 5000表示当前方法执行完毕5000ms后,Spring scheduling会再次调用该方法
  20. public void testFixDelay() {
  21. logger.info("===fixedDelay: 第{}次执行方法", fixedDelayCount++);
  22. }
  23. @Scheduled(fixedRate = 5000) //fixedRate = 5000表示当前方法开始执行5000ms后,Spring scheduling会再次调用该方法
  24. public void testFixedRate() {
  25. logger.info("===fixedRate: 第{}次执行方法", fixedRateCount++);
  26. }
  27. @Scheduled(initialDelay = 1000, fixedRate = 5000) //initialDelay = 1000表示延迟1000ms执行第一次任务
  28. public void testInitialDelay() {
  29. logger.info("===initialDelay: 第{}次执行方法", initialDelayCount++);
  30. }
  31. @Scheduled(cron = "0 0/1 * * * ?") //cron接受cron表达式,根据cron表达式确定定时规则
  32. public void testCron() {
  33. logger.info("===initialDelay: 第{}次执行方法", cronCount++);
  34. }
  35. }

使用 @Scheduled来创建定时任务 这个注解用来标注一个定时任务方法。 

通过看 @Scheduled源码可以看出它支持多种参数:

    (1)cron:cron表达式,指定任务在特定时间执行;

    (2)fixedDelay:表示上一次任务执行完成后多久再次执行,参数类型为long,单位ms;

    (3)fixedDelayString:与fixedDelay含义一样,只是参数类型变为String;

    (4)fixedRate:表示按一定的频率执行任务,参数类型为long,单位ms;

    (5)fixedRateString: 与fixedRate的含义一样,只是将参数类型变为String;

    (6)initialDelay:表示延迟多久再第一次执行任务,参数类型为long,单位ms;

    (7)initialDelayString:与initialDelay的含义一样,只是将参数类型变为String;

    (8)zone:时区,默认为当前时区,一般没有用到。

2、开启定时任务:


  1. package com.accord;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.scheduling.annotation.EnableScheduling;
  5. @SpringBootApplication
  6. @EnableScheduling
  7. public class SpringBootCron2Application {
  8. public static void main(String[] args) {
  9. SpringApplication.run(SpringBootCron2Application.class, args);
  10. }
  11. }

注:这里的 @EnableScheduling  注解,它的作用是发现注解 @Scheduled的任务并由后台执行。没有它的话将无法执行定时任务。

引用官方文档原文:

@EnableScheduling ensures that a background task executor is created. Without it, nothing gets scheduled.

3、执行结果(单线程)

就完成了一个简单的定时任务模型,下面执行springBoot观察执行结果:

从控制台输入的结果中我们可以看出所有的定时任务都是在同一个线程池用同一个线程来处理的,那么我们如何来并发的处理各定时任务呢,请继续向下看。

4、多线程处理定时任务:

看到控制台输出的结果,所有的定时任务都是通过一个线程来处理的,我估计是在定时任务的配置中设定了一个SingleThreadScheduledExecutor,于是我看了源码,从ScheduledAnnotationBeanPostProcessor类开始一路找下去。果然,在ScheduledTaskRegistrar(定时任务注册类)中的ScheduleTasks中又这样一段判断:


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

这就说明如果taskScheduler为空,那么就给定时任务做了一个单线程的线程池,正好在这个类中还有一个设置taskScheduler的方法:


  1. public void setScheduler(Object scheduler) {
  2. Assert.notNull(scheduler, "Scheduler object must not be null");
  3. if (scheduler instanceof TaskScheduler) {
  4. this.taskScheduler = (TaskScheduler) scheduler;
  5. }
  6. else if (scheduler instanceof ScheduledExecutorService) {
  7. this.taskScheduler = new ConcurrentTaskScheduler(((ScheduledExecutorService) scheduler));
  8. }
  9. else {
  10. throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass());
  11. }
  12. }

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


  1. package com.accord.task;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.scheduling.annotation.SchedulingConfigurer;
  4. import org.springframework.scheduling.config.ScheduledTaskRegistrar;
  5. import java.util.concurrent.Executors;
  6. /**
  7. * 多线程执行定时任务
  8. * @author 王久印
  9. * 2018年3月1日
  10. */
  11. @Configuration
  12. //所有的定时任务都放在一个线程池中,定时任务启动时使用不同都线程。
  13. public class ScheduleConfig implements SchedulingConfigurer {
  14. @Override
  15. public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  16. //设定一个长度10的定时任务线程池
  17. taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
  18. }
  19. }

5、执行结果(并发)

通过控制台输出的结果看出每个定时任务都是在通过不同的线程来处理了。

Spring Boot 定时任务单线程和多线程的更多相关文章

  1. Spring Boot定时任务应用实践

    在Spring Boot中实现定时任务功能,可以通过Spring自带的定时任务调度,也可以通过集成经典开源组件Quartz实现任务调度. 一.Spring定时器 1.cron表达式方式 使用自带的定时 ...

  2. Spring Boot定时任务运行一段时间后自动关闭的解决办法

    用Spring Boot默认支持的 Scheduler来运行定时任务,有时在服务器运行一段时间后会自动关闭.原因:Schedule默认是单线程运行定时任务的,即使是多个不同的定时任务,默认也是单线程运 ...

  3. spring boot 定时任务

    定时任务实现方式 三种: 1) Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务. 最早的时候就是这样写定时任务的. 2) 开源的第三方框 ...

  4. spring boot.定时任务问题记录(TaskScheduler/ScheduledExecutorService异常)

    一.背景 spring boot的定时任务非常简单,只需要在启动类中加上@EnableScheduling注解,然后在对应的方法上配置@Scheduled就可以了,系统会自动处理并按照Schedule ...

  5. (14)Spring Boot定时任务的使用【从零开始学Spring Boot】

    本文介绍在 Spring Boot 中如何使用定时任务,使用非常简单,就不做过多说明了. com.kfit.base.scheduling.SchedulingConfig: package com. ...

  6. Spring Boot (十一): Spring Boot 定时任务

    在实际的项目开发工作中,我们经常会遇到需要做一些定时任务的工作,那么,在 Spring Boot 中是如何实现的呢? 1. 添加依赖 在 pom.xml 文件中只需引入 spring-boot-sta ...

  7. Spring Boot 定时任务 @Scheduled

    项目开发中经常需要执行一些定时任务,比如在每天凌晨,需要从 implala 数据库拉取产品功能活跃数据,分析处理后存入到 MySQL 数据库中.类似这样的需求还有许多,那么怎么去实现定时任务呢,有以下 ...

  8. Spring Boot 定时任务 Quartz 使用教程

    Quartz是一个完全由java编写的开源作业调度框架,他使用非常简单.本章主要讲解 Quartz在Spring Boot 中的使用. 快速集成 Quartz 介绍 Quartz 几个主要技术点 Qu ...

  9. spring -boot定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现

    spring 定时任务 quartz 基于  MethodInvokingJobDetailFactoryBean 实现 依赖包 如下 <dependencies> <depende ...

随机推荐

  1. How to Integrate .NET Projects with Jenkins

    https://www.swtestacademy.com/jenkins-dotnet-integration/ 8) Unit Tests and Test Coverage Settings D ...

  2. css中的绝对定位和相对定位(详解,总结)

    css中的绝对定位和相对定位(详解,总结) 总结: 设置绝对定位或者相对定位后都从文档中浮起来了,区别是相对定位还占着原来的位置,绝对定位不占着原来的位置,可以种z-index来改变元素的浮动的堆叠次 ...

  3. CNN tensorflow text classification CNN文本分类的例子

    from:http://deeplearning.lipingyang.org/tensorflow-examples-text/ TensorFlow examples (text-based) T ...

  4. POJ 3579 Median (二分)

                                                                                                         ...

  5. Codeforces--630I--Parking Lot(规律)

     I - Parking Lot Crawling in process... Crawling failed Time Limit:500MS     Memory Limit:65536KB  ...

  6. [POI 2008] BLO

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1123 [算法] 首先,如果一个点不是割点,那么,去掉该点后不连通的有序点对就为 : ...

  7. python3用list实现栈

    工作中遇到的需求,****代表标签数据别的信息: D01 ******** 1 ******** D01 ******** 2 ******** D01 ******** 3 ******** D01 ...

  8. python mysql数据库 'latin-1' codec can't encode character错误问题解决

    "UnicodeEncodeError:'latin-1' codec can't encode character ..."     This is because MySQLd ...

  9. javascript 原型(prototype 、__proto__、函数、对象)

    一.类型 1.JavaScript中分为值类型(string/boolean/null/number/undefind).引用类型(数组.对象.函数): 2.数组.函数.对象都是对象: 对象是由函数创 ...

  10. 记录一下Junit测试MongoDB,获取MongoTemplate

    只是自己记录一下,测试MongoDB帮助类时,没有配置文件的测试 public class HelperTest { MongoTemplate template; @Before public vo ...