SpringBoot整合Schedule详解和优化实战

news2024/12/23 22:52:15

文章目录

  • 前言
  • 为什么选择Spring Schedule
  • Cron表达式
  • 简单示例
    • 测试结果
    • 优化方案


前言

Spring Schedule是Spring框架提供的一种简单的定时任务解决方案。它是基于Java的@Scheduled注解,可以让我们在不影响主线程的情况下,定时、周期性地执行任务。

为什么选择Spring Schedule

选择Spring Schedule作为定时任务的原因主要有以下几点:

  • 简单易用:Spring Schedule的使用非常简单,只需要在方法上添加@Scheduled注解,就可以将该方法变为定时任务。
  • 集成方便:如果你的项目已经是Spring框架,那么使用Spring Schedule不需要额外引入其他依赖,只需要简单的配置即可。
  • 支持CRON表达式:Spring Schedule支持CRON表达式,这使得我们可以非常灵活地配置定时任务的执行时间。
  • 支持异步执行:Spring Schedule支持异步执行任务,这意味着定时任务的执行不会阻塞主线程。

Cron表达式

Cron 表达式是一个字符串,由多个时间字段组成,用空格分隔。一个标准的 Cron 表达式有 6 个或 7 个字段,分别表示秒、分钟、小时、日期、月份、星期以及(可选的)年份。

  • 秒(0-59)
  • 分(0-59)
  • 时(0-23)
  • 日(1-31)
  • 月(1-12 或 JAN-DEC)
  • 周(1-7 或 SUN-SAT)
  • 年(可选,留空表示任意年份)

除了上述基本的取值范围外,Cron 表达式还支持一些特殊字符,如:

*:代表所有可能的值。例如,使用 * 表示每分钟、每小时或每月等。
/:用于指定一个增量。例如,0/15 表示从 0 分钟开始,每隔 15 分钟执行一次。
-:用于指定一个范围。例如,10-20 表示从 10 到 20。
,:用于列举多个取值。例如,MON,WED,FRI 表示星期一、星期三和星期五。
?:用于天或星期字段,表示无需指定具体值。

简单示例

这里我做了一个简单的示例:这里写了两个定时任务,同一个时间往数据库里面插入数据,每个任务插入1000条数据。

Application.class

@EnableScheduling
@SpringBootApplication
@MapperScan("org.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

这里记得要有@EnableScheduling注解,才能使用定时任务。

ScheduledService.class

package org.example.service;

import org.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ScheduledService {

    @Autowired
    UserService userService;

    @Scheduled(cron = "0 08 10 * * ?")
    public void scheduledMethod(){
        System.out.println("第一个定时任务开始:"+ LocalDateTime.now());
        List<User> list = new ArrayList<User>();
        for(int i = 0;i<1000;i++){
            User user = new User();
            user.setId((long)i);
            user.setName("keaizp");
            user.setAge(25);
            list.add(user);
        }
        for (User user : list) {
            userService.insert(user);
        }
        System.out.println("第一个定时任务结束:"+ LocalDateTime.now());

    }


    @Scheduled(cron = "0 08 10 * * ?")
    public void Method2(){
        System.out.println("第二个定时任务开始:"+ LocalDateTime.now());
        List<User> list = new ArrayList<User>();
        for(int i = 1000;i<2000;i++){
            User user = new User();
            user.setId((long)i);
            user.setName("keaizp");
            user.setAge(25);
            list.add(user);
        }
        for (User user : list) {
            userService.insert(user);
        }
        System.out.println("第二个定时任务结束:"+ LocalDateTime.now());

    }
}

测试结果


可以看到定时任务会出现积压现象,虽然两个定时任务是设置同一时间的,但是第二个定时任务先执行,等第二个定时任务执行完成,第一个定时任务才开始执行。两个定时任务一共用时3分48秒。

优化方案

可以考虑使用异步执行的方式,使得任务的执行不会阻塞任务调度的进程。Spring Schedule默认是单线程执行任务的,如果有多个任务需要并行执行,那么可能会出现任务执行的延迟。这种情况下,可以考虑使用Spring Schedule的并行任务执行功能,通过配置TaskScheduler来实现。

package org.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {

    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

在这里插入图片描述
运行结果可以看到两个任务是并行执行的,两个任务完成一共用时1分54秒,效率大大得到提升!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/715704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue+ant design vue实现搜索区域form

1.要实现的效果&#xff1a; form部分form-item自动铺开&#xff0c;间距适当&#xff0c;屏幕大小不同能根据屏幕大小变化。 2.vue组件中的代码示例 重点html代码&#xff1a; <!-- 搜索区域 --><div class"table-page-search-wrapper"><a-form la…

vue 七款低代码平台对比

vue 七款低代码平台对比 摘要平台表单设计form-generatorLowCodeEngine 可视化设计OpenDataVGoView 门户设计AgileBPM轻流云程低代码平台 摘要 调研低代码平台时看了很多网站&#xff0c;被我大概分为了三种&#xff1a;页面设计、可视化设计、门户设计&#xff0c;其中功能也…

【vue3中使用swiper组件】

【vue3中使用swiper组件】超详细保姆级教程 效果展示简介版本安装Swiper用法完整代码展示html静态展示js逻辑展示&#xff08;vue3 --- ts&#xff09;官方文档导入模块 css样式展示 &#xff08;自行更改所需&#xff09;官方文档样式 效果展示 简介版本 安装Swiper 项目终端中…

Observability:Synthetic monitoring - 合成监测入门

从我们的全球测试基础设施监控关键用户旅程&#xff0c;并了解网络和前端性能对用户体验的影响。 全面了解你的网站性能、功能和可用性&#xff08;从开发到生产&#xff09;&#xff0c;并在客户之前发现问题。合成监测&#xff08;synthetic monitoring&#xff09;使你能够模…

关于表单提交

一、表单实例 <!-- 把表单信息放入到表格当中&#xff0c;显示的内容更加整齐 --><form action"" method"get"><h1 align"center">用户注册</h1><input type"hidden" name"action" value"l…

正则表达式 - 语法 | 一看就懂!!!(二)

目录 一、正则表达式 - 语法 二、普通字符 三、非打印字符 四、特殊字符 五、限定符 &#xff08;一&#xff09;限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。 &#xff08;二&#xff09;正则表…

Eureka注册失败解决

根据查看网上资料发现是服务端自己自己注册了&#xff0c;所以需要自己关闭服务端注册 加上两行代码 fetch-registry: false register-with-eureka: false 即可注册成功

初级保育员专业知识生活管理考试题库及答案

​本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题…

「深度学习之优化算法」(八)萤火虫算法

1. 萤火虫算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读) 萤火虫算法(Firefly Algorithm,FA)是一种模仿萤火虫之间信息交流,相互吸引集合,警戒危险。算法的原理简单,但实现过程较为复杂,而且算法的提出时间不长,算法的改进、优化处于初级阶段,国内外相应的…

大数据面试题-算法题

目录 1.时间复杂度、空间复杂度理解 2.常见算法求解思想 3.基本算法 3.1冒泡排序 3.2 快速排序 3.3 归并排序 3.4 遍历二叉树 3.5 二分查找 3.6 小青蛙跳台阶 3.7 最长回文子串 3.8 数字字符转化成IP 1.时间复杂度、空间复杂度理解 在计算机算法理论中&#xff0…

Nginx【Nginx核心指令(Gzip压缩指令)、Nginx场景实践(浏览器缓存、防盗链)】(七)-全面详解(学习总结---从入门到深化)

目录 Nginx核心指令_Gzip压缩指令 Nginx场景实践_浏览器缓存 Nginx场景实践_防盗链 Nginx核心指令_Gzip压缩指令 Nginx开启Gzip压缩功能&#xff0c; 可以使网站的css、js 、xml、html 文件 在传输时进行压缩&#xff0c;提高访问速度, 进而优化Nginx性能! Gzip压缩作用 将…

使用OpenCV工具包成功实现人脸检测与人脸识别,包括传统视觉和深度学习方法(附完整代码,吐血整理......)

使用OpenCV工具包实现人脸检测与人脸识别&#xff08;吐血整理&#xff01;&#xff09; OpenCV实现人脸检测OpenCV人脸检测方法基于Haar特征的人脸检测Haar级联检测器预训练模型下载Haar 级联分类器OpenCV-Python实现 基于深度学习的人脸检测传统视觉方法与深度学习方法对比 O…

爱不释手的六款IDEA神仙插件,开发效率翻倍!

一、前言 作为一名开发人员&#xff0c;在众多的 IDE 中&#xff0c;IntelliJ IDEA 无疑是最受欢迎和强大的选择。 除了其本身的功能外&#xff0c;IntelliJ IDEA 还支持各种强大的插件&#xff0c;这些插件可以进一步增强开发体验和效率。 这些插件就像是一些神奇的存在&…

uni-app如何生成海报图片

项目场景&#xff1a; 在uni-app中&#xff0c;通过点击邀请分享海报的方式&#xff0c;可以展示不同的海报&#xff0c;并通过扫描海报上的二维码来实现用户之间的关系绑定&#xff0c;从而实现分销功能&#xff1b;每次生成的海报样式都可能不同&#xff0c;可以根据后台配置…

Java实现PDF转Word【收集整理】

首先感谢 Mgg9702 博主提供的转换依赖包处理&#xff0c;关于如何获得一个破解的pdf转word我这里就不追述了&#xff0c;有需要去看&#xff1a; https://blog.csdn.net/Mgg9702/article/details/124987483?spm1001.2014.3001.5506 我这里主要涉及到整理一个pdf转word的jar工…

Spring Boot原理分析 | SpringApplication、Yaml、Properties

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Spring Boot Spring开源框架&#xff0c;轻量级的Java开发框架&#xff0c;解决企业级应用开发的复杂性而创建&#xff0c;简化开发 基于POJO的轻量级和最小侵入型编程…

【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(6月 30 日论文合集)

文章目录 一、分割|语义相关(8篇)1.1 MIS-FM: 3D Medical Image Segmentation using Foundation Models Pretrained on a Large-Scale Unannotated Dataset1.2 KITE: Keypoint-Conditioned Policies for Semantic Manipulation1.3 SeMLaPS: Real-time Semantic Mapping with La…

labelme的json标签和图像改变分辨率,再将json转换为YOLO的txt格式进行实例分割

最近在做一个分割数据集&#xff0c;训练数据时由于图像数据太大一直爆显存&#xff0c;然后就找了找同时resize图像和json的脚本&#xff0c;然后转换为YOLO格式一直出问题&#xff0c;标签和目标位置对不上&#xff0c;也是困扰了好久&#xff0c;终于解决&#xff0c;记录一…

惠普笔记本U盘重装Win10系统步骤

当惠普笔记本出现系统故障或需要清除所有数据时&#xff0c;通过使用U盘重新安装Win10系统是一个常见且有效的解决方法。重新安装系统可以解决许多问题&#xff0c;并为用户提供一个干净、流畅的操作环境。以下小编将为用户介绍惠普笔记本U盘重装Win10系统步骤。请注意&#xf…

手把手教学,Python 游戏编程之实现飞机大战(含源代码)

文章目录 一、游戏设定 1、游戏界面展示和设定 二、实现过程 1.我方飞机 2、敌方飞机 3、定义武器 4、武器补充库 5、主模块 总结&#xff1a; 前言 我想大家都是有玩过类似飞机大战的射击类游戏&#xff0c;也享受目标被消除通过后带来的愉悦感。 那么如果用Python来实现飞机…