Springboot实战篇--Springboot框架通过@Scheduled实现定时任务

简介: Spring Boot的Scheduled定时任务无需额外Maven依赖,通过`@EnableScheduling`开启。任务调度有两种方式:fixedRate和fixedDelay,前者任务结束后立即按设定间隔执行,后者在任务完成后等待设定时间再执行。更灵活的是cron表达式,例如`0 0 3 * * ?`表示每天3点执行。实现定时任务时,需注意默认单线程执行可能导致的任务交错,可通过自定义线程池解决。

一、开启定时任务方法

Scheduled定时任务是Spring boot自身提供的功能,所以不需要引入Maven依赖包

在项目入口main方法上加注解

<code class="language-plaintext hljs">@EnableScheduling //开启定时任务</code>

二、不同定时方式的解析

1.fixedDelay和fixedRate,单位是毫秒,它们的区别就是:

   fixedRate就是每隔多长时间执行一次。(开始------->X时间------>再开始)。如果间隔时间小于任务执行时间,上一次任务执行完成下一次任务就立即执行。如果间隔时间大于任务执行时间,就按照每隔X时间运行一次。

   而fixedDelay是当任务执行完毕后一段时间再次执行。(开始--->结束(隔一分钟)开始----->结束)。上一次执行任务未完成,下一次任务不会开始。

2.cron表达式:灵活

举例说明

表达式

 

说明

0 0 3 * * ?

 

每天3点执行

0 5 3 * * ?

 

每天3点5分执行

0 5 3 ? * *

 

每天3点5分执行,与上面作用相同

0 5/10 3 * * ?

 

每天3点的 5分,15分,25分,35分,45分,55分这几个时间点执行

0 10 3 ? * 1

 

每周星期天,3点10分 执行,注:1表示星期天

0 10 3 ? * 1#3

 

每个月的第三个星期,星期天 执行,#号只能出现在星期的位置

   第一位,表示秒,取值0-59

   第二位,表示分,取值0-59

   第三位,表示小时,取值0-23

   第四位,日期天/日,取值1-31

   第五位,日期月份,取值1-12

   第六位,星期,取值1-7,星期一,星期二...,注:不是第1周,第二周的意思,另外:1表示星期天,2表示星期一。

   第七位,年份,可以留空,取值1970-2099

cron中,还有一些特殊的符号,含义如下:

()星号:可以理解为每的意思,每秒,每分,每天,每月,每年...

(?)问号:问号只能出现在日期和星期这两个位置。

(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12

(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四

(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60 另:/y,等同于0/y

cron表达式在线:在线Cron表达式生成器

三、实现定时任务

<code class="language-plaintext hljs">@Component

public class ScheduledJobs{//表示方法执行完成后5秒再开始执行

   @Scheduled(fixedDelay=5000)

   public void fixedDelayJob() throws InterruptedException{

       System.out.println("fixedDelay 开始:"+newDate());

       Thread.sleep(10*1000);

       System.out.println("fixedDelay 结束:"+newDate());}//表示每隔3秒

   @Scheduled(fixedRate=3000)

   public void fixedRateJob()throws InterruptedException{

       System.out.println("===========fixedRate 开始:"+newDate());

       Thread.sleep(5*1000);

       System.out.println("===========fixedRate 结束:"+newDate());}//表示每隔10秒执行一次

   @Scheduled(cron="0/10 * * * * ? ")

   public void cronJob(){

       System.out.println("=========================== ...>>cron...."+newDate());}}</code>

运行结果如下:从运行结果上看,并未按照预期的时间规律运行。仔细看线程打印,竟然所有的定时任务使用的都是一个线程,所以彼此互相影响。

<code class="language-plaintext hljs">===========fixedRate 结束:Tue Jul 0919:53:04 CST 2019pool-1-thread-1

fixedDelay 开始:Tue Jul 0919:53:04 CST 2019pool-1-thread-1

fixedDelay 结束:Tue Jul 0919:53:14 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:14 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:16 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:16 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:18 CST 2019pool-1-thread-1===========================...>>cron....Tue Jul 0919:53:18 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:18 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:20 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:20 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:22 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:22 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:24 CST 2019pool-1-thread-1

fixedDelay 开始:Tue Jul 0919:53:24 CST 2019pool-1-thread-1

fixedDelay 结束:Tue Jul 0919:53:34 CST 2019pool-1-thread-1===========================...>>cron....Tue Jul 0919:53:34 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:34 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:36 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:36 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:38 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:38 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:40 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:40 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:42 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:42 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:44 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:44 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:46 CST 2019pool-1-thread-1===========fixedRate 开始:Tue Jul 0919:53:46 CST 2019pool-1-thread-1===========fixedRate 结束:Tue Jul 0919:53:48 CST 2019pool-1-thread-1

fixedDelay 开始:Tue Jul 0919:53:48 CST 2019pool-1-thread-1

fixedDelay 结束:Tue Jul 0919:53:58 CST 2019pool-1-thread-1===========================...>>cron....Tue Jul 0919:53:58 CST 2019pool-1-thread-1</code>

四、解决定时任务单线程运行的问题

<code class="language-plaintext hljs">@Configuration

@EnableScheduling

public class ScheduleConfig implements SchedulingConfigurer{

 

   @Override

   public void configureTasks(ScheduledTaskRegistrar taskRegistrar){

       taskRegistrar.setScheduler(scheduledTaskExecutor());}

 

   @Bean

   public Executor scheduledTaskExecutor(){return Executors.newScheduledThreadPool(3);//指定线程池大小}}</code>

再次运行上面的程序,运行时间规律就符合期望了。


相关文章
|
23天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
152 1
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
37 0
|
27天前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
43 1
Spring 框架:Java 开发者的春天
|
19天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
37 2
|
19天前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
76 1
|
27天前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
1月前
|
人工智能 Java API
阿里云开源 AI 应用开发框架:Spring AI Alibaba
近期,阿里云重磅发布了首款面向 Java 开发者的开源 AI 应用开发框架:Spring AI Alibaba(项目 Github 仓库地址:alibaba/spring-ai-alibaba),Spring AI Alibaba 项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。本文将详细介绍 Spring AI Alibaba 的核心特性,并通过「智能机票助手」的示例直观的展示 Spring AI Alibaba 开发 AI 应用的便利性。示例源
|
1月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。