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 {
    @Override
    public 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫实战入门:豆瓣电影Top250(保你会,不会来打我)

文章目录 需求所需第三方库requests模块lxml模块了解 lxml模块和xpath语法xpath语法-基础节点选择语法 实战教程完整代码 需求 目标网站: https://movie.douban.com/top250 需求: 爬取电影中文名、英文名、电影详情页链接、导演、主演、上映年份、国籍、类型、评分、评分人数, …

振弦采集仪的操作方法及数据处理技术的一般步骤

振弦采集仪的操作方法及数据处理技术的一般步骤 岩土工程监测中,河北稳控科技振弦采集仪是用来测量土壤或岩石中的振动特性的仪器。下面是振弦采集仪的操作方法及数据处理技术的一般步骤: 1. 准备工作:安装振弦采集仪的支架或支架&#xff0…

文心一言 VS 讯飞星火 VS chatgpt (215)-- 算法导论16.2 2题

二、设计动态规划算法求解 0-1 背包问题,要求运行时间为 O(nW),n为商品数量,W是小偷能放进背包的最大商品总重量。如果要写代码,请用go语言。 文心一言: 0-1 背包问题是一个典型的动态规划问题,其目标是在…

如何高效接入 Flink:Connecter / Catalog API 核心设计与社区进展

摘要:本文整理自阿里云实时计算团队 Apache Flink Committer 和 PMC Member 任庆盛在 FFA 2023 核心技术专场(二)中的分享,内容主要分为以下四部分: 1. Source API 2. Sink API 3. 将 Connecter 集成至 Table /SQL A…

运动想象 (MI) 迁移学习系列 (9) : 数据对齐(EA)

运动想象迁移学习系列:数据对齐(EA) 0. 引言1. 迁移学习算法流程2. 欧式对齐算法流程3. 与RA算法进行对比4. 实验结果对比5. 总结欢迎来稿 论文地址:https://ieeexplore.ieee.org/abstract/document/8701679 论文题目:Transfer Le…

macOS Ventura 13.6.5 (22G621) Boot ISO 原版可引导镜像下载

macOS Ventura 13.6.5 (22G621) Boot ISO 原版可引导镜像下载 3 月 8 日凌晨,macOS Sonoma 14.4 发布,同时带来了 macOS Ventru 13.6.5 和 macOS Monterey 12.7.4 安全更新。 macOS Ventura 13.6 及更新版本,如无特殊说明皆为安全更新&…

Python数据分析-pandas3

1.pandas的作用: numpy能够帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据。 2.pandas之Series创建: 3.pandas之Series切片和索引 4.缺失值处理 5.常用的统计…

【阅读论文】智能数据可视分析技术综述

智能数据可视分析技术综述 文章结构 中文引用格式: 骆昱宇, 秦雪迪, 谢宇鹏, 李国良. 智能数据可视分析技术综述. 软件学报, 2024, 35(1): 356–404. http://www.jos.org.cn/1000-9825/6911.htm

深度学习环境搭建

前言 因为一些原因,我需要更换一台新的服务器来跑深度学习。 这篇文章记录了我在新的远程服务器上搭建深度学习环境的过程。 基本情况 本人采用笔记本电脑连接远程服务器的方式跑深度学习代码。 笔记本电脑环境: 远程服务器环境: 环境搭…

PHP<=7.4.21 Development Server源码泄露漏洞 例题

打开题目 dirsearch扫描发现存在shell.php 非预期解 访问shell.php&#xff0c;往下翻直接就看到了flag.. 正常解法 访问shell.php 看见php的版本是7.3.33 我们知道 PHP<7.4.21时通过php -S开起的WEB服务器存在源码泄露漏洞&#xff0c;可以将PHP文件作为静态文件直接输…

西门子PLC常用底层逻辑块分享_单/双输出电磁阀

文章目录 前言一、功能概述二、单输出电磁阀程序编写1.创建自定义数据类型2.创建FB功能块“单输出电磁阀”3.编写程序 三、双输出电磁阀程序编写1.创建自定义数据类型2.创建FB功能块“双输出电磁阀”3.编写程序 前言 本文分享一个自己编写的电磁阀控制逻辑块。 一、功能概述 …

搭建谷歌Gemini

前言 Gemini是Google AI于2023年发布的大型语言模型&#xff0c;拥有强大的文本生成、理解和转换能力。它基于Transformer模型架构&#xff0c;并使用了大量文本和代码数据进行训练。Gemini可以执行多种任务&#xff0c;包括&#xff1a; 生成文本&#xff1a;可以生成各种类…

COX回归影响因素分析的基本过程与方法

在科学研究中&#xff0c;经常遇到分类的结局&#xff0c;主要是二分类结局&#xff08;阴性/阳性&#xff1b;生存/死亡&#xff09;&#xff0c;研究者可以通过logistic回归来探讨影响结局的因素&#xff0c;但很多时候logistic回归方法无法使用。如比较两种手段治疗新冠肺炎…

Cookie和Session介绍

1、Cookie的一些重要结论&#xff08;令牌&#xff0c;类似就诊卡记住我们的信息&#xff09;&#xff1a; &#xff08;1&#xff09;Cookie从哪里来&#xff1a;服务器返回给浏览器的&#xff0c;通常是首次访问/登录成功之后&#xff08;cookie是在header中传输&#xff09…

稀碎从零算法笔记Day17-LeetCode:有效的括号

题型&#xff1a;栈 链接&#xff1a;20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述&#xff08;红字为笔者添加&#xff09; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 …

flstudio教程如何设置成中文 flstudio基础教程 flstudio免费

Fl studio编曲软件总共有英文和中文两种语言供用户选择&#xff0c;对于我们来说&#xff0c;更习惯于使用中文版本的flstudio编曲软件&#xff0c;包括我自己也比较习惯于使用中文版本的flstudio&#xff0c;同时也能提高工作效率。Flstudio编曲软件默认语言是英文&#xff0c…

力扣 322 零钱兑换

题目描述 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬币的数量是无限的。 示例 1&#xff1a; 输入&#xff1a;coins [1, 2, 5…

VUE基础易错点概述

文章目录 Post/Get请求的区别插槽验证规则的使用ref与$refslable 与 :lable 两个页面间的切换在主页面中&#xff0c;自定义子组件在子页面中 .sync修饰符 本文主要介绍了 Post与Get请求、插槽、验证器的使用、ref与$refs、lable 与 :lable、两个页面的切换以及自定义组件 用于…

圈子社交系统-多人语音-交友-陪玩-活动报名-商城-二手论坛-源码交付,支持二开!

圈子小程序适用于多种场景&#xff0c;涵盖了各个领域的社交需求。以下是一些常见的适用场景&#xff1a; 兴趣社区&#xff1a; 用户可以加入自己感兴趣的圈子&#xff0c;与志同道合的人一起讨论交流&#xff0c;分享经验和知识。 行业交流&#xff1a; 各个行业可以建立自…