Spring Boot 中@Scheduled是单线程还是多线程?

在开发Spring Boot应用程序时,定时任务是一项常见的需求。Spring Boot提供了@Scheduled注解,可用于将方法标记为定时任务,并在预定的时间间隔内执行。那么@Scheduled注解的执行方式是单线程执行,还是多线程执行?@Scheduled注解的执行方式会不会产生线程不安全的问题?

以下总结@Scheduled注解的执行方式,并解释它在Spring Boot中的多线程行为。

一:案例演示

新建两个定时任务,一个是每2秒执行一次,一个是每3秒执行一次

@Component
public class ScheduledTest {@Scheduled(cron = "0/2 * * * * ? ")public void testTask1(){Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println(threadName+"-->"+ "testTask1-->"+LocalDateTime.now());}@Scheduled(cron = "0/3 * * * * ? ")public void testTask2(){Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println(threadName+"-->"+"testTask2-->"+ LocalDateTime.now());}
}

image-20240314003034203

发现这两个任务的线程是同一个,由此可以推测Spring Boot提供的@Scheduled注解默认是以单线程方式执行。下面看下源码:Scheduled提供的核心类ScheduledTaskRegistrar、ContextLifecycleScheduledTaskRegistrar

image-20240314003748775

ContextLifecycleScheduledTaskRegistrar 在bean实例化后会调 其父类ScheduledTaskRegistrar提供的scheduleTasks()方法,并且创建了单例的调度线程池

image-20240314003939023

image-20240314004104324

由此可见,Spring Boot提供的@Scheduled注解默认是以单线程方式执行。

有的人可能会想会不会是在同一个类中的方法导致结果是公用了同一个线程?不要猜,去验证!

image-20240314005121888

把testTask1和testTask2分别放在不同的类,结果共用同一个线程。

二:在单线程下会产生什么问题?

单线程环境下,如果某个任务处理时间很长,有可能导致其他任务阻塞。testTask1()休眠一小时模拟长时间处理任务,testTask2()一直处于阻塞状态。

@Component
public class ScheduledTest1 {@Scheduled(cron = "0/2 * * * * ? ")public void testTask1() throws InterruptedException {Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println("testTask1 开始执行~");TimeUnit.HOURS.sleep(1);System.out.println(threadName + "-->" + "testTask1-->" + LocalDateTime.now());}@Scheduled(cron = "0/3 * * * * ? ")public void testTask2() {Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println(threadName + "-->" + "testTask2-->" + LocalDateTime.now());}
}

image-20240314005903928

因此对于这种场景,我们可以考虑把@Scheduled配置成多线程环境下执行,解决@Scheduled在单线程环境下可能产生的问题。

三:@Scheduled支持多线程吗?

既然SchedulingConfigurer默认是创建了单例线程池,那我们是不是可以自定义线程池当做参数传给Scheduled呢?

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));}
}

案例验证代码

@Component
public class ScheduledTest6 {@Scheduled(cron = "0/2 * * * * ? ")public void testTask1() throws InterruptedException {Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println("testTask1 开始执行~");TimeUnit.HOURS.sleep(1);System.out.println(threadName + "-->" + "testTask1-->" + LocalDateTime.now());}@Scheduled(cron = "0/3 * * * * ? ")public void testTask2() {Thread thread = Thread.currentThread();String threadName = thread.getName();System.out.println(threadName + "-->" + "testTask2-->" + LocalDateTime.now());}
}

image-20240314011506586

由截图可知,有5个线程,1、2、5都正常处理testTask2任务,3、4两个线程正在处理testTask1()任务,因此多线程环境下可以解决单线程环境下可能导致的任务阻塞的问题。

更多细节可以关注我的个人主页 www.zhouy.work

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

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

相关文章

docker小白第十二天

docker小白第十二天 docker network简介 docker不启动时默认的网络情况。 # 停止docker服务 systemctl stop docker.socket systemctl stop docker # 查看docker镜像 docker images输入查看docker镜像命令后,显示未连接到docker服务器 docker启动时网络情况 sy…

使用BBDown下载bilibili视频的方法

一款命令行式哔哩哔哩下载器. Bilibili Downloader. 下载地址 https://github.com/nilaoda/BBDown 功能 番剧下载(Web|TV|App) 课程下载(Web) 普通内容下载(Web|TV|App) 合集/列表/收藏夹/个人空间解析 多分P自动下载 选择指定分P进行下载 选择指定清晰度进行下载 下载外挂字幕…

html--bug

文章目录 html html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>老师</title><style>body {background-color: #008000;margin: 0px;cursor: none;overflow: hidden;}</style></head><bod…

88. 合并两个有序数组 (Swift版本)

题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并…

深度解析Java JDK 1.8中Stream流的源码实现:带你探寻数据流的奥秘

文章目录 一、 Stream流概述1.1 什么是Stream流&#xff0c;以及它的主要特点和优势1.2 Stream流的基本操作&#xff1a;过滤、映射、排序等 二、 Stream流源码解析2.1 接口和基本概念2.2 创建流2.3 源码分析2.3.1 流的起始2.3.2 流的初始2.3.3 认识BaseStream2.3.4 Stream接口…

java-ssm-jsp基于java的餐厅点餐系统的设计与实现

java-ssm-jsp基于java的餐厅点餐系统的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全

RabbitMQ:1.概述及安装

概述 AMQP协议 MQ Message Queue&#xff08;消息队列&#xff09;是在消息的传输过程中保存消息的容器&#xff0c;多用于系统之间的异步通信 AMQP Advanced Message Queuing Protocol(高级消息队列协议)是一个网络协议&#xff0c;2006年AMQP规范发布【类比HTTP】 专门为消…

基于单片机的公交车IC卡操作系统的设计

目 录 摘 要 III Abstract IV 前 言 1 第一章 绪论 2 1.1 设计的背景和意义 2 1.2 设计的现状和发展 2 1.3 设计的目的与意义 2 第二章 总体设计 4 2.1 总体方案的设计与实现 4 2.1.1 主要设计的内容 4 2.1.2 系统的总体设计 4 2.2 系统方案论证 5 2.2.1 单片机的选择 6 2.2.2…

Ubuntu虚拟机的IP总频繁变化,导致Xshell断开连接

文章目录 一、IP变化的原因二、解决方法&#xff1a;固定IP三、参考文章 一、IP变化的原因 1.DHCP协议 虚拟机系统(Ubuntu、CentOS、UOS等Linux系统)启动后&#xff0c;加入本地局域网网络时&#xff0c;会向本地网络申请租约一个IP地址&#xff0c;租约时长不定。我这里租约时…

独立开发的轻量级简洁开源论坛BBS PHP源码 – 2023新版发布

最新的轻量级开源论坛php源码发布啦&#xff01;这是一款独立开发的论坛系统&#xff0c;可以帮助你快速地开发出你想要的网站。 如果你是PHP初学者&#xff0c;这款论坛系统非常适合你入门学习。不过&#xff0c;需要注意的是&#xff0c;由于它并没有进行商业化改造&#xf…

如何正确地设置Outlook SMTP发送电子邮件?

Outlook SMTP发送邮件配置方法&#xff1f;Outlook怎么开启SMTP&#xff1f; 在使用Outlook发送邮件时&#xff0c;正确设置SMTP服务器是确保邮件能够顺利发送的关键步骤。接下来&#xff0c;就让AokSend一起探讨如何正确地设置Outlook SMTP发送电子邮件吧&#xff01; Outlo…

Notepad++从文件夹查找文本内容

目录 一、背景二、Notepad搜索2.1 测试用例2.2 操作说明 一、背景 在日常的办公、学习或编程中&#xff0c;我们时长会遇到需要在大量文件中搜索特定文本内容的情况&#xff1a; 无论是快速定位某个项目中的代码片段&#xff1b;还是检索文档资料库中的相关信息等。 掌握如何…

义乌购关键字搜索API接口技术详解与代码示例

义乌购关键字搜索API接口技术详解与代码示例 在电子商务蓬勃发展的今天&#xff0c;义乌购作为国内知名的批发市场平台&#xff0c;为广大商家和消费者提供了丰富的商品资源。为了方便开发者快速接入义乌购平台&#xff0c;实现商品信息的搜索与获取&#xff0c;义乌购开放了关…

音频读取之wave和liborsa

wave 常见的语音信号处理python库有librosa, scipy, soundfile等等。wave库是python的标准库&#xff0c;对于python来说相对底层&#xff0c;wave不支持压缩/解压&#xff0c;但支持单声道/立体声语音的读取。 读取音频 import wave #导入库file_path D:/ba.wav #文件路径…

Vue2 + node.js项目

1、Vue2 vue2主要功能包括登入、退出、用户权限、表格的增删改查、文件下载。 Vue2项目地址https://gitee.com/www6/finance1.git 2、node.js编写后端接口 2.1、项目初始化 后端地址https://gitee.com/www6/finance-backend.git 创建项目 npm install -g koa-generator …

有趣的前端知识(三)

推荐阅读 有趣的前端知识&#xff08;一&#xff09; 有趣的前端知识&#xff08;二&#xff09; 文章目录 推荐阅读JS内置对象JS外部对象BOM模型history对象screen对象navigator对象 DOM&#xff08;文档对象模型&#xff09;DOM的方法&#xff08;对于节点的操作&#xff09…

【打工日常】docker部署快速开发海报工具

一、fastposter海报生成器介绍 fastposter 是一款海报生成器&#xff0c;它能够让您快速、轻松地创建各种类型的海报。 只需上传一张背景图&#xff0c;然后在需要的位置添加文字、图片、二维 、头像等组件。点击生成代码按钮&#xff0c;直接获取各种语言 SDK 的调用代码&…

智能物流新纪元:分布式I/O模块重塑仓储自动化

随着工业4.0概念的深入人心&#xff0c;物流行业正在经历前所未有的变革。在这个过程中&#xff0c;物流企业必须积极走向工业自动化、智能化&#xff0c;进而提高物流效率&#xff0c;降低物流成本&#xff0c;以便更好地满足客户和市场的需求。智能物流、仓库自动化已然是趋势…

Java实现PDF文字内容识别,结合OCR实现PDF图片实现

使用插件&#xff1a;UMI-OCR、PDFBOX 实现思路&#xff1a;通过PDFBOX识别PDF文字&#xff0c;如果是图片&#xff0c;则识别不出来&#xff0c;再调用OCR进行识别返回文字&#xff1b;OCR识别较慢&#xff0c;长图识别不出来&#xff0c;目前HTTP方式只支持图片格式&#xf…

【设计模式】二、UML 类图与面向对象设计原则 之 UML概述

二、UML 类图与面向对象设计原则 &#xff08;一&#xff09;UML 类图 UML 概述类与类的UML图示类之间的关系 &#xff08;二&#xff09;面向对象设计原则 单一职责原则&#xff08;Single Responsibility Principle, SRP&#xff09;开闭原则&#xff08;Open-Closed Princip…