Spring Boot整合@Scheduled定时计划

SpringBoot集成了@Scheduled的相关依赖(org.springframework.scheduling.annotation.Scheduled);我们只需要直接使用即可。

@Scheduled注解的使用步骤:

第一步:在启动类上面启用定时任务

第二步:在要定时执行的方法上面,加上@Scheduled注解,并指定执行间隔

第三步:把@Scheduled所在的类注入到容器中

第四步:启动启动类(注:启动启动类之后,定时任务就开始了)

注意:Spring的定时任务默认是单线程的。如果有多个定时任务,那么执行起来时间会有问题;这时就需要开启多线程了(先把基本知识介绍完,本文末尾再介绍线程问题)。

注:如果只有一个定时任务,那么我们可以将这个定时任务单独拿出来作为一个微服务;这样一来就不需要开启多线程了。

@Scheduled的定时策略:

cronExpression定义时间规则,cron表达式由6或7个空格分隔的时间字段组成: 秒  分  时  日  月  星期  年(可选);

注:如果Spring中使用的是Quartz等的话,那么cron表达式是支持七位的;如果Spring中使用的是Spring Task等的话,
      那么cron表达式只支持六位。

字段

允许值

允许的特殊字符

0-59

, - * /

0-59

, - * /

0-23

, - * /

1-31

, - * ? / L W C

1-12   或  JAN-DEC

, - * /

星期

1-7   或   SUN-SAT

注:1是星期天,7是星期六

, - * ? / L C #

1970-2099

, - * /

特殊字符:

/ : 指定每隔多久执行一次    如: 0/5 * * * * ? : 每5秒执行一次

注:此时/的“分子”位置的值为:定义此次计划执行时间允许值的最小值,如:

34/10 * * * * ? : 表示此次计划只在34,44,54秒时执行,在4,14,24秒时不会执行。

注: */10 等价于 0/10

* : 通配,每个单位时间都要执行    如:"*"在分钟的字段域里表示“每分钟”

? : 只在日期域或者星期域中使用   使用场景示例:月份中的日期和星期中的日期这两个元素时互斥的时候应该通过设置一个问号来表明不想设置那个字段。

- : 用来指定一个范围,在这个时间范围内,就要执行。

如:10-12  在小时域意味着    10点、11点、12点,那么在这个时间域内要执行Scheduled计划

, : 用来指定多个时间值(一般用于不相邻的时间)

如:0,13,45 * * * * ?表示 在第0秒,13秒,45秒时要执行Scheduled计划。

# : 只允许在星期域中出现。

如:6#3表示本月第三周的星期五(6表示星期五,3表示第三周)。

L : last的省略写法

如果出现在日域,那么表示一个月的最后一天

如: 0 * * L 3 ? 表示 三月的最后一天,每小时每分钟都要执行一次

如果出现在星期域,那么表示一个月的最后一个星期几

如: 0 * * * 3 7L 表示 三月的最后一个星期六(注:7表示星期六),每小时每分钟都要执行一次

W : 指向该日,如果该日不是工作日,那么指向本月里离得最近的一个工作日。

0 * * 15W * ? 表示每个月的15号为工作日(注:如果15号为节假日的话,那么指向离它最近的一个本月内的工作日)。

C : 允许在日期域和星期域出现。

示例:

"0 0 10,14,16 * * ?"

每天上午10点,下午2点,4点

"0 0/30 9-17 * * ?"

朝九晚五工作时间内每半小时

"0 0 12 ? * WED"

表示每个星期三中午12点

"0 0 12 * * ?"

每天中午12点触发

"0 15 10 ? * *"

每天上午10:15触发

"0 15 10 * * ?"

每天上午10:15触发

"0 15 10 * * ? *"

每天上午10:15触发

"0 15 10 * * ? 2005"

2005年的每天上午10:15触发

"0 * 14 * * ?"

在每天下午2点到下午2:59期间的每1分钟触发

"0 0/5 14 * * ?"

在每天下午2点到下午2:55期间的每5分钟触发

"0 0/5 14,18 * * ?"

在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

"0 0-5 14 * * ?"

在每天下午2点到下午2:05期间的每1分钟触发

"0 10,44 14 ? 3 WED"

每年三月的星期三的下午2:10和2:44触发

"0 15 10 ? * MON-FRI"

周一至周五的上午10:15触发

"0 15 10 15 * ?"

每月15日上午10:15触发

"0 15 10 L * ?"

每月最后一日的上午10:15触发

"0 15 10 ? * 6L"

每月的最后一个星期五上午10:15触发

"0 15 10 ? * 6L 2002-2005"

2002年至2005年的每月的最后一个星期五上午10:15触发

"0 15 10 ? * 6#3"

每月的第三个星期五上午10:15触发

线程问题:

在同一个线程中,如果执行某一个定时任务所需时间较长,那么就可能影响其他所需时间较短的定时任务。

即:当所需时间较长的方法抢占到了线程;在其还没有运行完时,其他的定时任务错过了“定时”。

如:

控制台打印出的结果为:

使用多线程解决此问题:

配置线程池(SpringBoot配置线程池无需引入其他依赖,直接使用注解即可):

给出文字版:

//线程池配置

@Configuration

@EnableAsync

public class ThreadPoolConfig {

@Bean

public Executor asyncExecutor() {

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

// 配置核心线程数

executor.setCorePoolSize(5);

// 配置最大线程数

executor.setMaxPoolSize(5);

// 配置队列大小

executor.setQueueCapacity(99999);

// 配置线程池中的线程的名称前缀

executor.setThreadNamePrefix("async-executor-");

// rejection-policy:当pool已经达到max size的时候,如何处理新任务

// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

// 执行初始化

executor.initialize();

return executor;

}

}

在有@Scheduled定时计划的方法上,使用线程池:

此时,控制台打印出的信息为:

如上图所示:方法Two每5秒执行一次;方法One每10秒执行一次(截图我只截了一点,下面的也遵循这个规律)

由此可见:开启多线程使用线程池后,解决了之前的问题。

原文地址:https://www.cnblogs.com/xinglongbing521/p/10351550.html

时间: 2024-12-09 13:57:27

Spring Boot整合@Scheduled定时计划的相关文章

Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的介绍请阅读Apache Kafka简介与安装(一),关于Kafka安装请阅读Apache Kafka安装,关于Kafka集群环境搭建请阅读Apache Kafka集群环境搭建 .这里关于服务器环境搭建不在赘述. Spring Kafka整合Spring Boot创建生产者客户端案例 创建一个kafk

Spring Boot 定时任务 @Scheduled

项目开发中经常需要执行一些定时任务,比如在每天凌晨,需要从 implala 数据库拉取产品功能活跃数据,分析处理后存入到 MySQL 数据库中.类似这样的需求还有许多,那么怎么去实现定时任务呢,有以下几种实现方式. Java 定时任务的几种实现方式 基于 java.util.Timer 定时器,实现类似闹钟的定时任务 使用 Quartz.elastic-job.xxl-job 等开源第三方定时任务框架,适合分布式项目应用 使用 Spring 提供的一个注解: @Schedule,开发简单,使用比

spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】

最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要的表导入数据库 官网上有不同数据库的脚本,找到对应的,导入即可 3. java 代码 将quartz 的相关配置文件,配置为暴露bean,方便后期引用. 有一处关键的地方,就是注入spring 上下文,也可以算是一个坑.如果,不注入spring 上下文,那么新添加的定时任务job,是新new 的一个

spring boot 整合spring Data JPA+Spring Security+Thymeleaf框架(上)

最近上班太忙所以耽搁了给大家分享实战springboot 框架的使用. 下面是spring boot 整合多个框架的使用. 首先是准备工作要做好. 第一  导入框架所需的包,我们用的事maven 进行对包的管理. 以上的举例是本人的H5DS的真实的后台管理项目,这个项目正在盛情融资中,各位多多捧点人场.关注一下软件发展的动态,说不定以后就是您的生活不可或缺的软件哟. 点击打开链接.闲话少说.现在切入正题. 第二,写点配置文件 第三,spring data -设计一个简单的po关系,这里需要下载一

spring boot整合jsp的那些坑(spring boot 学习笔记之三)

Spring Boot 整合 Jsp 步骤: 1.新建一个spring boot项目 2.修改pom文件 <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <depend

Spring boot整合jsp

这几天在集中学习Spring boot+Shiro框架,因为之前view层用jsp比较多,所以想在spring boot中配置jsp,但是spring boot官方不推荐使用jsp,因为jsp相对于一些模板引擎,性能都比较低,官方推荐使用thymeleaf,但是Spring boot整合jsp的过程已经完成,在这里记录一下. 这篇博文是在LZ上篇文章spring boot+mybatis整合基础上写的,开发工具仍然是Intellij idea.这篇文章的重点是Intellij idea的设置,否

企业分布式微服务云SpringCloud SpringBoot mybatis (十三)Spring Boot整合MyBatis

Spring中整合MyBatis就不多说了,最近大量使用Spring Boot,因此整理一下Spring Boot中整合MyBatis的步骤.搜了一下Spring Boot整合MyBatis的文章,方法都比较老,比较繁琐.查了一下文档,实际已经支持较为简单的整合与使用.下面就来详细介绍如何在Spring Boot中整合MyBatis,并通过注解方式实现映射. 整合MyBatis 新建Spring Boot项目,或以Chapter1为基础来操作 pom.xml中引入依赖 这里用到spring-bo

spring boot 整合kafka 报错 Exception thrown when sending a message with key=&#39;null&#39; and payload=JSON to topic proccess_trading_end: TimeoutException: Failed to update metadata after 60000 ms.

org.springframework.kafka.support.LoggingProducerListener- Exception thrown when sending a message with key='null' and payload='{"dataDts":["20180329","20180328","20180327","20180326","20180323"]

activeMQ入门+spring boot整合activeMQ

最近想要学习MOM(消息中间件:Message Oriented Middleware),就从比较基础的activeMQ学起,rabbitMQ.zeroMQ.rocketMQ.Kafka等后续再去学习. 上面说activeMQ是一种消息中间件,可是为什么要使用activeMQ? 在没有使用JMS的时候,很多应用会出现同步通信(客户端发起请求后需要等待服务端返回结果才能继续执行).客户端服务端耦合.单一点对点(P2P)通信的问题,JMS可以通过面向消息中间件的方式很好的解决了上面的问题. JMS规