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 线程池管理,提高系统性能,减少资源消耗,并且代码更易维护! 🚀

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

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

相关文章

9、交付手段-强化肌肉记忆(随身工具箱)

一、交付工具箱 当临时遇到各类交付棘手问题时&#xff0c;大脑里记住交付工具的使用场景&#xff0c;有利于快速决策&#xff0c;将这些工具转为肌肉记忆&#xff0c;能够快速灵活处理交付中的各类问题&#xff0c;蜕变为交付之星 1、复杂项目&#xff1a;WBS分解、日站会、…

【概念】Node.js,Express.js MongoDB Mongoose Express-Validator Async Handler

1. Node.js 定义&#xff1a;Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff0c;允许你在服务器端运行 JavaScript 代码。作用&#xff1a;它使得开发者可以使用 JavaScript 编写服务器端代码&#xff0c;从而实现前后端使用同一种语言。比喻&#xff1a…

【GPT入门】第22课 langchain LCEL介绍

【GPT入门】第22课 langchain LCEL介绍 1. LCEL介绍与特点2. 原生API与LCEL的对比2. 简单demo 1. LCEL介绍与特点 LCEL 即 LangChain Expression Language&#xff0c;是 LangChain 推出的一种声明式语言&#xff0c;用于简化和优化在 LangChain 框架内构建复杂链和应用的过程…

数据结构——单链表list

前言&#xff1a;大家好&#x1f60d;&#xff0c;本文主要介绍数据结构——单链表 目录 一、单链表 二、使用步骤 1.结构体定义 2.初始化 3.插入 3.1 头插 3.2 尾插 3.3 按位置插 四.删除 4.1头删 4.2 尾删 4.3 按位置删 4.4按值删 五 统计有效值个数 六 销毁…

堆排序:力扣215.数组中的第K个大元素

一、问题描述 在一个整数数组 nums 中&#xff0c;需要找出第 k 个最大的元素。这里要注意&#xff0c;我们要找的是数组排序后的第 k 个最大元素&#xff0c;而不是第 k 个不同的元素。例如&#xff0c;对于数组 [3,2,1,5,6,4]&#xff0c;当 k 2 时&#xff0c;第 2 个最大…

C语言(25)

一.数据在内存中的存储 1.整数在内存中的存储 整数在内存中以二进制的形式储存&#xff0c;分别为原码&#xff0c;补码&#xff0c;反码 有符号的整数&#xff0c;在上述三种形式都有符号位和数值位两个部分&#xff0c;符号位为0是正数&#xff0c;1是负数&#xff0c;最高…

鸿蒙开发-一多开发之媒体查询功能

在HarmonyOS中&#xff0c;使用ArkTS语法实现响应式布局的媒体查询是一个强大的功能&#xff0c;它允许开发者根据不同的设备特征&#xff08;如屏幕尺寸、屏幕方向等&#xff09;动态地调整UI布局和样式。以下是一个使用媒体查询实现响应式布局的实例&#xff1a; 1. 导入必要…

Docker运行hello-world镜像失败或超时:Unable to find image ‘hello-world:latest‘ locally Trying to pull reposi

Docker运行hello-world镜像失败或超时&#xff0c;报错&#xff1a;Unable to find image ‘hello-world:latest’ locally Trying to pull repository docker.io/library/hello-world … /usr/bin/docker-current: missing signature key. See ‘/usr/bin/docker-current run …

MySQL连接较慢原因分析及解决措施

文章目录 整体说明一、问题现象二、问题分析2.1、DNS反向解析问题2.2、网络问题2.3、SSL/TLS协商问题2.4、自动补全的延迟 三、问题解决 摘要&#xff1a; MySQL连接较慢原因分析及解决措施 关键词&#xff1a; MySQL、连接缓慢、客户端、参数设置 整体说明 在使用MySQL的时候…

doris:安全概览

oris 提供以下机制管理数据安全&#xff1a; 身份认证&#xff1a;Doris 支持用户名/密码与 LDAP 认证方式。 内置认证&#xff1a;Doris 内置了用户名/密码的认证方式&#xff0c;可以自定义密码策略&#xff1b; LDAP 认证&#xff1a;Doris 可以通过 LDAP 服务集中管理用户…

C++之文字修仙小游戏

1 效果 1.1 截图 游戏运行&#xff1a; 存档&#xff1a; 1.2 游玩警告 注意&#xff01;不要修改装备概率&#xff0c;装备的概率都是凑好的数字。如果想要速升&#xff0c;修改灵石数量 2 代码 2.1 代码大纲 1. 游戏框架与初始化 控制台操作&#xff1a;通过 gotoxy() …

Docker安装部署RabbitMQ

Docker安装部署RabbitMQ 本文介绍了如何在Linux&#xff08;CentOS 7&#xff09;系统环境下的Docker上安装部署RabbitMQ的详细过程。 目录 Docker安装部署RabbitMQ一、环境准备1.Linux环境2.Docker3.停止并移除现有的 RabbitMQ 镜像和容器 二、安装部署RabbitMQ1.拉取 RabbitM…

【MyBatis Plus 逻辑删除详解】

文章目录 MyBatis Plus 逻辑删除详解前言什么是逻辑删除&#xff1f;MyBatis Plus 中的逻辑删除1. 添加逻辑删除字段2. 实体类的配置3. 配置 MyBatis Plus4. 使用逻辑删除5. 查询逻辑删除的记录 MyBatis Plus 逻辑删除详解 前言 MyBatis Plus 是一个强大的持久化框架&#xf…

线性代数(1)用 excel 计算鸡兔同笼

线性代数excel计算鸡兔同笼 案例&#xff1a;鸡兔同笼问题的三种解法&#xff08;递进式教学&#xff09;一、问题描述二、方程式解法&#xff08;基础版&#xff09;步骤解析 三、线性代数解法&#xff08;进阶版&#xff09;1. 方程组转化为矩阵形式2. 矩阵求解&#xff08;逆…

Flask中使用WTForms处理表单验证

在 Flask 中&#xff0c;WTForms 是一个用于 处理表单验证 的库&#xff0c;可以与 Flask 结合&#xff0c;提供表单验证、数据清理、错误提示等功能。 1. 安装 Flask-WTF 首先安装 Flask-WTF&#xff1a; pip install Flask-WTFFlask-WTF 是 WTForms 的 Flask 扩展&#xff…

24.策略模式实现日志

日志的介绍 计算机中的日志是记录系统和软件运行中发送事件的文件&#xff0c;主要作用是监控运行状态、记录异常信息&#xff0c;帮助快速定位问题并支持程序员进行问题修复。它是系统维护、故障排查和安全管理的重要工具。 日志格式以下几个指标是必须得有的&#xff1a; •…

【网络】简单的 Web 服务器架构解析,包含多个服务和反向代理的配置,及非反向代理配置

这张图片描述了一个简单的 Web 服务器架构&#xff0c;包含多个服务和反向代理的配置。以下是对每个部分的详细解释&#xff0c;帮助你理解其中的技术内容&#xff1a; 1. Web Server: ifn666.com 这是你的主域名&#xff08;ifn666.com&#xff09;&#xff0c;所有服务都通过…

​​​​​​​大语言模型安全风险分析及相关解决方案

大语言模型的安全风险可以从多个维度进行分类。 从输入输出的角度来看,存在提示注入、不安全输出处理、恶意内容生成和幻觉错误等风险; 从数据层面来看,训练数据中毒、敏感信息泄露和模型反演攻击是主要威胁; 模型自身则面临拒绝服务和盗窃的风险; 供应链和插件的不安全引…

贪心算法——c#

贪心算法通俗解释 贪心算法是一种"每一步都选择当前最优解"的算法策略。它不关心全局是否最优&#xff0c;而是通过局部最优的累积来逼近最终解。优点是简单高效&#xff0c;缺点是可能无法得到全局最优解。 一句话秒懂 自动售货机找零钱&#xff1a;用最少数量的…

STM32 - 在机器人领域,LL库相比HAL优势明显

在机器人控制器、电机控制器等领域的开发&#xff0c;需要高实时性、精细化控制或者对代码执行效率、占用空间有较高要求。所以&#xff0c;大家常用的HAL库明显不符合要求。再加上&#xff0c;我们学习一门技术&#xff0c;一定要学会掌握底层的原理。MCU开发的底层就是寄存器…