当前位置: 首页 > article >正文

Spring Boot使用线程池创建多线程

Spring Boot 2 中,可以使用 @Autowired 注入 线程池ThreadPoolTaskExecutorExecutorService),从而管理线程的创建和执行。以下是使用 @Autowired 方式注入线程池的完整示例。


1. 通过 @Autowired 注入 ThreadPoolTaskExecutor

步骤 1:配置线程池

创建 ThreadPoolTaskExecutor@Bean 配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;@Configuration
public class ThreadPoolConfig {@Bean(name = "customTaskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);  // 核心线程数executor.setMaxPoolSize(10);  // 最大线程数executor.setQueueCapacity(25); // 任务队列容量executor.setThreadNamePrefix("Async-Executor-"); // 线程名前缀executor.initialize();return executor;}
}

步骤 2:使用 @Autowired 注入线程池

Service 层,通过 @Autowired 注入 ThreadPoolTaskExecutor 并执行任务:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;import java.util.concurrent.Future;@Service
public class AsyncTaskService {private static final Logger logger = LoggerFactory.getLogger(AsyncTaskService.class);@Autowired@Qualifier("customTaskExecutor") // 通过 @Qualifier 指定 Bean 名称private ThreadPoolTaskExecutor customTaskExecutor;// 提交异步任务public void runAsyncTask() {customTaskExecutor.execute(() -> {logger.info("异步任务执行,线程名:{}", Thread.currentThread().getName());try {Thread.sleep(2000); // 模拟耗时任务} catch (InterruptedException e) {e.printStackTrace();}logger.info("异步任务完成,线程名:{}", Thread.currentThread().getName());});}// 提交带返回值的异步任务public Future<String> runAsyncTaskWithResult() {return customTaskExecutor.submit(() -> {logger.info("执行带返回值的异步任务,线程名:{}", Thread.currentThread().getName());Thread.sleep(2000);return "任务完成";});}
}

步骤 3:在 Controller 中调用

Controller 层,通过 @Autowired 调用 AsyncTaskService

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.Future;@RestController
@RequestMapping("/task")
public class AsyncTaskController {@Autowiredprivate AsyncTaskService asyncTaskService;@GetMapping("/run")public String runTask() {asyncTaskService.runAsyncTask();return "任务已提交";}@GetMapping("/runWithResult")public String runTaskWithResult() throws Exception {Future<String> result = asyncTaskService.runAsyncTaskWithResult();return "任务结果:" + result.get();}
}

2. 通过 @Autowired 注入 ThreadPoolTaskScheduler(适用于定时任务)

步骤 1:配置 ThreadPoolTaskScheduler

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configuration
public class TaskSchedulerConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5);  // 线程池大小scheduler.setThreadNamePrefix("Scheduled-Task-");scheduler.initialize();return scheduler;}
}

步骤 2:在 Service 中使用 @Autowired 注入

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;import java.util.concurrent.ScheduledFuture;@Service
public class ScheduledTaskService {private static final Logger logger = LoggerFactory.getLogger(ScheduledTaskService.class);@Autowiredprivate ThreadPoolTaskScheduler taskScheduler;public void scheduleTask() {ScheduledFuture<?> future = taskScheduler.scheduleAtFixedRate(() -> {logger.info("执行定时任务,线程名:{}", Thread.currentThread().getName());}, 5000);}
}

步骤 3:在 Controller 中调用

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/schedule")
public class ScheduleTaskController {@Autowiredprivate ScheduledTaskService scheduledTaskService;@GetMapping("/start")public String startScheduledTask() {scheduledTaskService.scheduleTask();return "定时任务已启动";}
}

3. 通过 @Autowired 注入 ExecutorService

如果你更喜欢 Java 原生的 ExecutorService,可以使用 @Bean 配置:

步骤 1:定义 ExecutorService 线程池

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@Configuration
public class ExecutorServiceConfig {@Beanpublic ExecutorService fixedThreadPool() {return Executors.newFixedThreadPool(5);}
}

步骤 2:在 Service 中注入 ExecutorService

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;import java.util.concurrent.ExecutorService;@Service
public class ExecutorServiceTask {private static final Logger logger = LoggerFactory.getLogger(ExecutorServiceTask.class);@Autowiredprivate ExecutorService executorService;public void executeTask() {executorService.execute(() -> {logger.info("执行任务,线程名:{}", Thread.currentThread().getName());});}
}

步骤 3:在 Controller 中调用

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/executor")
public class ExecutorServiceController {@Autowiredprivate ExecutorServiceTask executorServiceTask;@GetMapping("/run")public String runTask() {executorServiceTask.executeTask();return "任务已提交";}
}

总结

方式适用场景配置方式
ThreadPoolTaskExecutor普通异步任务 (@Asyncexecute)@Autowired private ThreadPoolTaskExecutor
ThreadPoolTaskScheduler定时任务@Autowired private ThreadPoolTaskScheduler
ExecutorService原生 Java 线程池@Autowired private ExecutorService

推荐方式

  • 使用 ThreadPoolTaskExecutor 结合 @Autowired 来管理异步任务(推荐)。
  • 使用 ThreadPoolTaskScheduler 进行定时任务调度。
  • 避免直接使用 ExecutorService,因为它不受 Spring 管理,不能动态调整线程池参数。

这样可以 充分利用 Spring Boot 线程池管理,提高系统性能,减少资源消耗,并且代码更易维护! 🚀

相关文章:

Spring Boot使用线程池创建多线程

在 Spring Boot 2 中&#xff0c;可以使用 Autowired 注入 线程池&#xff08;ThreadPoolTaskExecutor 或 ExecutorService&#xff09;&#xff0c;从而管理线程的创建和执行。以下是使用 Autowired 方式注入线程池的完整示例。 1. 通过 Autowired 注入 ThreadPoolTaskExecuto…...

PyTorch 深度学习实战(11):强化学习与深度 Q 网络(DQN)

在之前的文章中&#xff0c;我们介绍了神经网络、卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;、Transformer 等多种深度学习模型&#xff0c;并应用于图像分类、文本分类、时间序列预测等任务。本文将介绍强化学习的基本概念&#xff0…...

在Eclipse 中使用 MyBatis 进行开发,通常需要以下步骤:

在Eclipse 中使用 MyBatis 进行开发&#xff0c;通常需要以下步骤&#xff1a; 1. 创建 Maven 项目 首先&#xff0c;在 Eclipse 中创建一个 Maven 项目。如果你还没有安装 Maven 插件&#xff0c;可以通过 Eclipse Marketplace 安装 Maven 插件。 打开 Eclipse&#xff0c;选…...

Python学习第十九天

Django-分页 后端分页 Django提供了Paginator类来实现后端分页。Paginator类可以将一个查询集&#xff08;QuerySet&#xff09;分成多个页面&#xff0c;每个页面包含指定数量的对象。 from django.shortcuts import render, redirect, get_object_or_404 from .models impo…...

Adobe Premiere Pro2023配置要求

Windows 系统 最低配置 处理器&#xff1a;Intel 第六代或更新版本的 CPU&#xff0c;或 AMD Ryzen™ 1000 系列或更新版本的 CPU&#xff0c;需要支持 Advanced Vector Extensions 2&#xff08;AVX2&#xff09;。操作系统&#xff1a;Windows 10&#xff08;64 位&#xff…...

面试求助:接口测试用例设计主要考虑哪些方面?

一、基础功能验证 1. 正常场景覆盖 关键点&#xff1a;验证接口在合法输入下的正确响应&#xff08;状态码、数据结构、业务逻辑&#xff09;。 案例&#xff1a; json 复制 // 用户登录接口 输入&#xff1a;{"username": "合法用户", "password…...

C语言——变量与常量

C语言中的变量与常量&#xff1a;简洁易懂的指南 在C语言编程中&#xff0c;变量和常量是最基本的概念之一。理解它们的区别和使用方法对于编写高效、可维护的代码至关重要。本文将详细介绍C语言中的变量和常量&#xff0c;并通过图表和代码示例帮助你更好地理解。 目录 什么…...

考研408-数据结构完整代码 线性表的顺序存储结构 - 顺序表

线性表的顺序存储结构 - 顺序表 1. 顺序表的定义 ​ 用一组地址连续的存储单元依次存储线性表的数据元素&#xff0c;从而使逻辑上相邻的两个元素在物理位置上也相邻 2. 顺序表的特点 随机访问&#xff1a; 即通过首地址和元素序号可以在O(1) 时间内找到指定元素&#xff0…...

Windows环境下安装部署dzzoffice+onlyoffice的私有网盘和在线协同系统

安装前需要准备好Docker Desktop环境&#xff0c;可查看我的另一份亲测安装文章 https://blog.csdn.net/qq_43003203/article/details/146283915?spm1001.2014.3001.5501 1、安装配置onlyoffice 1、Docker 拉取onlyoffice容器镜像 管理员身份运行Windows PowerShell&#x…...

解决 Docker 镜像拉取超时问题:配置国内镜像源

在使用 Docker 的过程中&#xff0c;经常会遇到镜像拉取超时的问题&#xff0c;尤其是在国内网络环境下。这不仅会浪费大量的时间&#xff0c;还可能导致一些项目无法顺利进行。今天&#xff0c;我将分享一个简单而有效的解决方法&#xff1a;配置国内镜像源。 环境 操作系统 c…...

如何解决 Three.js 物体渲染的锯齿问题

在 Three.js 中&#xff0c;如果模型看起来不够平滑&#xff0c;或者在旋转视角时出现锯齿&#xff08;aliasing&#xff09;&#xff0c;可以通过以下方法来优化渲染效果。 1. 启用抗锯齿&#xff08;MSAA&#xff09; 默认情况下&#xff0c;Three.js 渲染器不会开启抗锯齿&…...

嵌入式八股,为什么单片机中不使用malloc函数

1. 资源限制 单片机的内存资源通常非常有限&#xff0c;尤其是RAM的大小可能只有几KB到几十KB。在这种情况下&#xff0c;使用 malloc 进行动态内存分配可能会导致内存碎片化&#xff0c;使得程序在运行过程中逐渐耗尽可用内存。 2. 内存碎片问题 malloc 函数在分配和释放内…...

【计量地理学】实验一 地理数据的基本统计分析

阅前提示&#xff1a; 计量地理学实验课的实验报告为当堂提交&#xff0c;相较以往实验报告缺少打磨与整理的时间&#xff0c;因此内容中不可避免出现相关错误&#xff01;&#xff01;&#xff01; 出于个人完美主义的原则本不愿发布&#xff08;其实就是黑历史&#xff09;…...

ChatPromptTemplate的使用

ChatPromptTemplate 是 LangChain 中专门用于管理多角色对话结构的提示词模板工具。它的核心价值在于&#xff0c;开发者可以预先定义不同类型的对话角色消息&#xff08;如系统指令、用户提问、AI历史回复&#xff09;&#xff0c;并通过数据绑定动态生成完整对话上下文。 1.…...

SQL Server查询优化

最常用&#xff0c;最有效的数据库优化方式 查询语句层面 避免全表扫描 使用索引&#xff1a;确保查询条件中的字段有索引。例如&#xff0c;查询语句 SELECT * FROM users WHERE age > 20&#xff0c;若 age 字段有索引&#xff0c;数据库会利用索引快速定位符合条件的记…...

Blender插件NodeWrangler导入贴图报错解决方法

Blender用NodeWrangler插件 CtrlShiftT 导入贴图 直接报错 解决方法: 用CtrlshiftT打开需要导入的材质文件夹时&#xff0c;右边有一个默认勾选的相对路径&#xff0c;取消勾选就可以了。 开启node wrangler插件&#xff0c;然后在导入贴图是取消勾选"相对路径"&am…...

QT中的宏

Q_UNUSED(event); 是 Qt 提供的一个宏&#xff0c;用于标记某个变量或参数在当前作用域中未被使用。它的主要作用是避免编译器发出“未使用变量”的警告。 背景 在 C 中&#xff0c;如果一个函数参数或变量在代码中没有被使用&#xff0c;编译器会发出警告&#xff0c;例如&a…...

java项目之基于ssm的药店药品信息管理系统(源码+文档)

项目简介 药店药品信息管理系统实现了以下功能&#xff1a; 个人信息管理 负责管理个人用户的信息。 员工管理 负责管理药店或药品管理机构的员工信息。 药品管理 负责管理药品的详细信息&#xff0c;可能包括药品名称、成分、剂量、价格、库存等。 进货管理 负责管理药品…...

论文分享 | HE-Nav: 一种适用于复杂环境中空地机器人的高性能高效导航系统

阿木实验室始终致力于通过开源项目和智能无人机产品&#xff0c;为全球无人机开发者提供强有力的技术支持&#xff0c;并推出了开源项目校园赞助活动&#xff0c;助力高校学子在学术研究与技术创新中取得更大突破。近日&#xff0c;香港大学王俊铭同学&#xff0c;基于阿木实验…...

【大语言模型】【个人知识库正式内容】提示工程:如何设计模型的提示语

知识库条目&#xff1a;提示工程&#xff0c;如何构建提示词。 &#x1f3d6;️ 当人人都能使用AI时&#xff0c;你如何才能变得更出彩&#xff1f;……让 AI 带有自己的Tag —— 一、简介 什么是提示语 (Prompt)&#xff1a; 提示语是用户输入给AI系统的指令或信息, 简单来说…...

ubuntu 24 安装 python3.x 教程

目录 注意事项 一、安装不同 Python 版本 1. 安装依赖 2. 下载 Python 源码 3. 解压并编译安装 二、管理多个 Python 版本 1. 查看已安装的 Python 版本 2. 配置环境变量 3. 使用 update-alternatives​ 管理 Python 版本 三、使用虚拟环境为项目指定特定 Python 版本…...

(十一) 人工智能 - Python 教程 - Python元组

更多系列教程&#xff0c;每天更新 更多教程关注&#xff1a;xxxueba.com 星星学霸 1 元组&#xff08;Tuple&#xff09; 元组是有序且不可更改的集合。在 Python 中&#xff0c;元组是用圆括号编写的。 实例 创建元组&#xff1a; thistuple ("apple", "b…...

【sql靶场】第13、14、17关-post提交报错注入保姆级教程

目录 【sql靶场】第13、14、17关-post提交报错注入保姆级教程 1.知识回顾 1.报错注入深解 2.报错注入格式 3.使用的函数 4.URL 5.核心组成部分 6.数据编码规范 7.请求方法 2.第十三关 1.测试闭合 2.列数测试 3.测试回显 4.爆出数据库名 5.爆出表名 6.爆出字段 …...

93.HarmonyOS NEXT窗口管理基础教程:深入理解WindowSizeManager

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT窗口管理基础教程&#xff1a;深入理解WindowSizeManager 文章目录 HarmonyOS NEXT窗口管理基础教程&#xff1a;深入理解WindowSiz…...

Python----数据分析(Pandas一:pandas库介绍,pandas操作文件读取和保存)

一、Pandas库 1.1、概念 Pandas是一个开源的、用于数据处理和分析的Python库&#xff0c;特别适合处理表格类数 据。它建立在NumPy数组之上&#xff0c;提供了高效的数据结构和数据分析工具&#xff0c;使得数据操作变得更加简单、便捷和高效。 Pandas 的目标是成为 Python 数据…...

基于WebRTC技术的EasyRTC嵌入式音视频SDK:多平台兼容与性能优化

在当今数字化、智能化的时代背景下&#xff0c;实时音视频通信技术已成为众多领域不可或缺的关键技术。基于WebRTC技术的EasyRTC嵌入式音视频SDK&#xff0c;凭借其在ARM、Linux、Windows、安卓、iOS等多平台上的兼容性&#xff0c;为开发者提供了强大的工具&#xff0c;推动了…...

【快速入门】MyBatis

一.基础操作 1.准备工作 1&#xff09;引入依赖 一个是mysql驱动包&#xff0c;一个是mybatis的依赖包&#xff1a; <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><vers…...

提升 React 应用性能:使用 React Profiler 进行性能调优

前言 在现代前端开发中&#xff0c;性能优化是一个不可忽视的重要环节。在 React 生态系统中&#xff0c;React Profiler 是一个强大的工具&#xff0c;它可以帮助我们检测和优化应用的性能。 本文将通过通俗易懂的语言介绍 React Profiler 的作用&#xff0c;并展示如何使用它…...

八、Prometheus 静态配置(Static Configuration)

所有的配置都可以用静态配置来监控,只不过用servicemonitor简单,但是域名需要静态配置 如果使用 Prometheus 静态配置(Static Configuration),确实不需要 ServiceMonitor、Service 和 Endpoints,但这也意味着失去了 Kubernetes 自动发现(Service Discovery, SD) 的能力…...

重生之我在学Vue--第16天 Vue 3 插件开发

重生之我在学Vue–第16天 Vue 3 插件开发 文章目录 重生之我在学Vue--第16天 Vue 3 插件开发前言一、插件的作用与开发思路1.1 插件能做什么&#xff1f;1.2 插件开发四部曲 二、开发全局通知插件2.1 插件基础结构2.2 完整插件代码&#xff08;带注释解析&#xff09;2.3 样式文…...