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

news2024/9/24 11:30:32

在开发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

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

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

相关文章

【Redis】Redis常用命令之Hash

1.hset:设置hash中指定的字段(field)的值(value)。 HSET key field value [field value ...]时间复杂度:插⼊⼀组field为O(1),插⼊N组field为O(N)。 返回值:添加的字段的个数。 2.hget&#xf…

【视觉三维重建】【论文笔记】Deblurring 3D Gaussian Splatting

去模糊的3D高斯泼溅,看Demo比3D高斯更加精细,对场景物体细节的还原度更高,[官网](https://benhenryl.github.io/Deblurring-3D-Gaussian-Splatting/) 背景技术 Volumetric rendering-based nerual fields&#xff1a…

邀请媒体到场报道与采访的优势分析

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 邀请媒体到场报道与采访的优势主要有: 提高知名度和曝光率:通过媒体的广泛传播,让更多人了解活动或品牌,增强其在公众中的认知度。 树立权…

自动化运维工具Ansible

目录 一.Ansible基本内容 1.定义 2.特点与优势 优势: (1)轻便性:无需在被控制服务器上安装客户端,Ansible基于ssh协议 (2)幂等性:大部分模块有幂等性,即如果输入sys…

Git概述及安装步骤

一、Git简介 Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。Git 易于学习,占地面积小,性能极快。它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CV…

鸿蒙 - 读取 rawfile 中的 json 文件

一、说明 在以下目录中存放了一份地区 json 文件。 我想要将其读出来,并且转为我的实体类。 二、技术实现 import common from ohos.app.ability.common import { CityEntity } from ./entity/CityEntity import util from ohos.util;/*** App 内置的地区数据* r…

pytorch之诗词生成3--utils

先上代码: import numpy as np import settingsdef generate_random_poetry(tokenizer, model, s):"""随机生成一首诗:param tokenizer: 分词器:param model: 用于生成古诗的模型:param s: 用于生成古诗的起始字符串,默认为空串:return: …

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

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

软考高级:软件工程单元测试(驱动模块、被测模块、桩模块)概念和例题

作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Qt 线程池 QThreadPool

一.Qt 线程池 QThreadPool介绍 Qt线程池是一种管理多个线程的并发编程模型,通过使用线程池可以提高性能、控制并发度、提供任务队列和简化线程管理。 在Qt中,线程池的使用主要涉及以下几个步骤: 创建任务类:需要定义一个任务类&am…

【计算机视觉】一、计算机视觉概述

文章目录 一、计算机视觉二、计算机视觉与其它学科领域的关系1、图像处理2、计算机图形学3、模式识别4、人工智能(AI)5、神经生理学与认知科学 三、计算机视觉的应用1. 人脸识别2. 目标检测3. 图像生成4. 城市建模5. 电影特效6. 体感游戏动作捕捉7. 虚拟…

Android 仿天通卫星对准(卫星在圆形卫星轨道上转动)效果实现

效果图 View源码 package com.android.circlescalebar.view;import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics…

linux对于文件操作其他命令

tac,与cat不同,tac可以倒序查看文件内容 管道符,可以将第一条命令的结果当作第二条命令的输入 more分屏显示文件内容 head,可以查看文件前多少行,tail可以查看文件后多少行

JavaEE之多线程(创建线程的五种写法)详解

😽博主CSDN主页: 小源_😽 🖋️个人专栏: JavaEE 😀努力追逐大佬们的步伐~ 目录 1. 前言 2. 操作系统"内核" 3. 创建线程的五种写法 (我们重点要掌握最后一种写法!!) 3.1 继承 Thread, 重写 run 3. 2 实现 Runnabl…

SpringBoot Servlet容器启动解析

介绍 容器架构 容器处理请求 容器启动全局流程解析 启动前准备 WebServer创建入口 WebServer创建 Servlet启动 Web容器工厂类加载解析 Web容器个性化配置 属性注入 工厂类初始化 BeanPostProcessor方法实现 定制化流程 面试题 请描述下Servlet容器启动流程?介绍下…

最新android icon和splashScreen适配兼容至2024android

android在12做了splashScreen的变动,即,android12有自带的screenSplash过渡,不论你是否自己有变化,都会插入该动画。 android8做了icon的巨大变动。13做了图标的主题兼容。 一、icon制作 制作 使用android自带的工具&#xff0…

Modbus -tcp协议使用第二版

1.1 协议描述 1.1.1 总体通信结构 MODBUS TCP/IP 的通信系统可以包括不同类型的设备: (1)连接至 TCP/IP 网络的 MODBUS TCP/IP 客户机和服务器设备; (2)互连设备,例如:在 TCP/IP…

外包干了5天,技术明显退步。。。。。

先说一下自己的情况,本科生,19年通过校招进入南京某软件公司,干了接近2年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

C# Onnx yolov8 building segmentation

目录 效果 模型信息 项目 代码 下载 C# Onnx yolov8 building segmentation 效果 模型信息 Model Properties ------------------------- date:2023-12-22T10:51:07.627471 author:Ultralytics task:segment license:AGPL-…

HBase分布式数据库的原理和架构

一、HBase简介 HBase是是一个高性能、高可靠性、面向列的分布式数据库,它是为了在廉价的硬件集群上存储大规模数据而设计的。HBase利用Hadoop HDFS作为其文件存储系统,且Hbase是基于Zookeeper的。 二、HBase架构 *图片引用 Hbase采用Master/Slave架构…