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

Springboot结合线程池的使用

1.使用配置文件配置线程的参数

配置文件

thread-pool:core-size: 100max-size: 100keep-alive-seconds: 60queue-capacity: 1

配置类

@Component
@ConfigurationProperties("thread-pool")
@Data
public class ThreadPoolConfig {private int coreSize;private int maxSize;private int keepAliveSeconds;private int queueCapacity;
}

2.配置线程池并使用

方式一:线程池结合CompletableFuture来实现

配置线程池类

@Configuration
public class ThreadPoolTask1 {@Autowiredprivate ThreadPoolConfig threadPoolConfig;@Bean("task1")public ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(threadPoolConfig.getCoreSize()); // 核心线程数executor.setMaxPoolSize(threadPoolConfig.getMaxSize()); // 最大线程数executor.setKeepAliveSeconds(threadPoolConfig.getKeepAliveSeconds()); // 非核心线程活跃时间executor.setQueueCapacity(threadPoolConfig.getQueueCapacity()); // 队列容量executor.setThreadNamePrefix("test-"); // 设置线程的前缀名executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 设置拒绝策略executor.setWaitForTasksToCompleteOnShutdown(false); // 是否在任务执行完后关闭线程池executor.initialize();return executor;}
}

CompletableFuture使用线程池进行调用

package com.example.demo;import com.example.demo.config.ThreadPoolTask1;
import com.sun.java.browser.plugin2.DOM;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.stream.Collectors;@RestController
public class Demo {@Autowiredprivate DemoServiceImpl demoService;@Autowired@Qualifier("task1")private ThreadPoolTaskExecutor threadPoolTask1;@GetMapping("thread1")public Map<String, String> thread1() {long start = System.currentTimeMillis();List<CompletableFuture<String>> futures = new ArrayList<>();Map<String, String> map = new HashMap<>();// 使用CompletableFuture的 supplyAsync来处理结果相当于submit, runAsync无返回相当于executefor (int i = 0; i < 100; i++) {int b = i;CompletableFuture<String> future = CompletableFuture.supplyAsync(() ->demoService.executorTask1(b), threadPoolTask1);futures.add(future);}// 获取结果集CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).whenComplete((v, th) ->futures.stream().forEach(item -> {String result = null;try {result = item.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}map.put(result.split("-")[1], result.split("-")[0]);})).join();long end = System.currentTimeMillis();map.put("当前时间",(end- start) + "");return map;}
}

任务类

    public String executorTask1(int i) {System.out.println("当前线程-" + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}if (i == 6) {throw new RuntimeException("cs");} else {return "aaa-" + i;}}

方式二:使用@EnableAsync和@Async方式实现

在启动类上加@EnableAsync注解

// 加上@EnableAsync注解,也可以在自己的配置类上加
@EnableAsync // 开启对异步任务的支持
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

编写线程池配置

// 也可以在此处加上@EnableAsync注解,入口类上不加
@Configuration
public class ThradPoolTask{@Autowiredprivate ThreadPoolConfig threadPoolConfig;@Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(threadPoolConfig.getCoreSize()); // 核心线程数executor.setMaxPoolSize(threadPoolConfig.getMaxSize()); // 最大线程数executor.setKeepAliveSeconds(threadPoolConfig.getKeepAliveSeconds()); // 非核心线程活跃时间executor.setQueueCapacity(threadPoolConfig.getQueueCapacity()); // 队列容量executor.setThreadNamePrefix("test-"); // 设置线程的前缀名executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 设置拒绝策略executor.setWaitForTasksToCompleteOnShutdown(false); // 是否在任务执行完后关闭线程池executor.initialize();return executor;}
}

使用

@RestController
public class Demo {@Autowiredprivate DemoServiceImpl demoService;@GetMapping("thread")public Map<String, String> thread() {long start = System.currentTimeMillis();Map<String, String> map = new HashMap<>();List<Future<String>> futures = new ArrayList<>();for (int i = 0; i < 100; i++) {Future<String> future = demoService.executorTask(i);futures.add(future);}int b = 1;futures.forEach(item -> {try {String result = item.get();map.put(result.split("-")[1], result.split("-")[0]);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}});long end = System.currentTimeMillis();map.put("当前时间",(end- start) + "");return map;}
}

任务类

    // 必须指明使用的是哪个线程池,taskExecutor不带的话用springboot默认注册的线程池// Future作为返回值,携带返回结果@Async("taskExecutor")public Future<String> executorTask(int i) {System.out.println("当前线程-" + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}if (i == 6) {throw new RuntimeException("cs");} else {// AsyncResult返回携带的结果return new AsyncResult<String>("aaa-" + i);}}

方式三:重写springboot默认的线程池配置

在启动类上加@EnableAsync注解

// 加上@EnableAsync注解,也可以在自己的配置类上加
@EnableAsync
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
@Configuration
public class ThreadPoolTask2 implements AsyncConfigurer {@Autowiredprivate ThreadPoolConfig threadPoolConfig;/*** 修改默认线程池的配置** @return*/@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(threadPoolConfig.getCoreSize()); // 核心线程数executor.setMaxPoolSize(threadPoolConfig.getMaxSize()); // 最大线程数executor.setKeepAliveSeconds(threadPoolConfig.getKeepAliveSeconds()); // 非核心线程活跃时间executor.setQueueCapacity(threadPoolConfig.getQueueCapacity()); // 队列容量executor.setThreadNamePrefix("test2-"); // 设置线程的前缀名executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 设置拒绝策略executor.setWaitForTasksToCompleteOnShutdown(false); // 是否在任务执行完后关闭线程池executor.initialize();return executor;}/*** 修改默认的异常处理* 注意:如果带有返回值Future,异常会被捕获,不会去执行该方法** @return*/@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return (ex, method, params) -> {System.out.println("任务执行的异常" + ex);System.out.println("执行的任务方法" + method.getName());for (Object param : params) {System.out.println("执执行任务的参数" + param);}};}
}

使用


@RestController
public class Demo {@Autowiredprivate DemoServiceImpl demoService;// 不带返回值的任务@GetMapping("thread2")public Map<String, String> thread2() {long start = System.currentTimeMillis();Map<String, String> map = new HashMap<>();List<Future<String>> futures = new ArrayList<>();for (int i = 0; i < 100; i++) {demoService.executorTask2(i);}return null;}// 带有返回值的任务@GetMapping("thread3")public Map<String, String> thread3() {long start = System.currentTimeMillis();Map<String, String> map = new HashMap<>();List<Future<String>> futures = new ArrayList<>();for (int i = 0; i < 100; i++) {Future<String> future = demoService.executorTask3(i);futures.add(future);}int b = 1;futures.forEach(item -> {String result = null;try {result = item.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}map.put(result.split("-")[1], result.split("-")[0]);});long end = System.currentTimeMillis();map.put("当前时间",(end- start) + "");return map;}
}

任务类

	// @Async不需要指定,使用默认即可// 出现异常会走AsyncUncaughtExceptionHandler方法@Asyncpublic void executorTask2(int i) {System.out.println("当前线程-" + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}int a = 1/0;}// 即使出现异常也不会走AsyncUncaughtExceptionHandler方法@Asyncpublic Future<String> executorTask3(int i) {System.out.println("当前线程-" + Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}if (i == 6) {throw new RuntimeException("cs");} else {return new AsyncResult<String>("aaa-" + i);}}

关于三种在执行过程中的异常

方式一:导致请求失败:最好在任务中进行处理
在这里插入图片描述

方式二:请求成功了,关于6的那条数据并没有返回给前端
在这里插入图片描述

方式三:请求成功了,关于6的那条数据并没有返回给前端

相关文章:

Springboot结合线程池的使用

1.使用配置文件配置线程的参数 配置文件 thread-pool:core-size: 100max-size: 100keep-alive-seconds: 60queue-capacity: 1配置类 Component ConfigurationProperties("thread-pool") Data public class ThreadPoolConfig {private int coreSize;private int ma…...

AOP工作流程

AOP工作流程3&#xff0c;AOP工作流程3.1 AOP工作流程流程1:Spring容器启动流程2:读取所有切面配置中的切入点流程3:初始化bean流程4:获取bean执行方法验证容器中是否为代理对象验证思路步骤1:修改App类,获取类的类型步骤2:修改MyAdvice类&#xff0c;不增强步骤3:运行程序步骤…...

Modbus相关知识点及问题总结

本人水平有限&#xff0c;写得不对的地方望指正 困惑&#xff1a;线圈状态的值是否是存储在线圈寄存器里面&#xff1f;是否有线圈寄存器的说法&#xff1f;网上有说法说是寄存器占两个字节&#xff0c;但线圈的最少操作单位是位。类似于继电器的通断状态&#xff0c;直接根据电…...

【MySQL】函数

文章目录1. DQL执行顺序2. 函数2.1 字符串函数2.2 数值函数2.3 日期函数2.4 流程函数2.5 窗口函数2.5.1 介绍2.5.2 聚合窗口函数2.5.3 排名窗口函数2.5.4 取值窗口函数1. DQL执行顺序 2. 函数 2.1 字符串函数 函数功能concat(s1,s2,…sn)字符串拼接&#xff0c;将s1,s2…sn拼…...

MySQL高级

一、基础环境搭建 环境准备&#xff1a;CentOS7.6&#xff08;系统内核要求是3.10以上的&#xff09;、FinalShell 1. 安装Docker 帮助文档 : https://docs.docker.com/ 1、查看系统内核&#xff08;系统内核要求是3.10以上的&#xff09; uname -r2、如果之前安装过旧版本的D…...

带你弄明白c++的4种类型转换

目录 C语言中的类型转换 C强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast RTTI 常见面试题 这篇博客主要是帮助大家了解和学会使用C中规定的四种类型转换。首先我们先回顾一下C语言中的类型转换。 C语言中的类型转换 在C语言中&#xff0c;如果赋…...

8个明显可以提升数据处理效率的 Python 神库

在进行数据科学时&#xff0c;可能会浪费大量时间编码并等待计算机运行某些东西。所以我选择了一些 Python 库&#xff0c;可以帮助你节省宝贵的时间 文章目录1、Optuna技术提升2、ITMO\_FS3、Shap-hypetune4、PyCaret5、floWeaver6、Gradio7、Terality8、Torch-Handle1、Optun…...

互联网公司吐槽养不起程序员,IT岗位的工资真是虚高有泡沫了?

说实话&#xff0c;看到这个话题的时候又被震惊到。 因为相比以往&#xff0c;程序员工资近年来已经够被压缩的了好嘛&#xff1f; 那些鼓吹泡沫论的&#xff0c;真就“何不食肉糜”了~~~ 而且这种逻辑就很奇怪&#xff0c; 程序员的薪资难道不是由行业水平决定么&#xff…...

Excel 进阶|只会 Excel 也能轻松搭建指标应用啦

现在&#xff0c;Kyligence Zen 用户可在 Excel 中对指标进行更进一步的探索和分析&#xff0c;能够实现对维度进行标签筛选、对维度基于指标值进行筛选和排序、下钻/上卷、多样化的透视表布局、本地 Excel 和云端 Excel 的双向支持等。业务人员和分析师基于现有分析习惯就可以…...

RabbitMQ中TTL

目录一、TTL1.控制后台演示消息过期2.代码实现2.1 队列统一过期2.2 消息过期一、TTL TTL 全称 Time To Live&#xff08;存活时间/过期时间&#xff09;。 当消息到达存活时间后&#xff0c;还没有被消费&#xff0c;会被自动清除。 RabbitMQ可以对消息设置过期时间&#xff0…...

Ceres简介及示例(4)Curve Fitting(曲线拟合)

文章目录1、Curve Fitting1.1、残差定义1.2、 Problem问题构造1.3、完整代码1.4、运行结果2、Robust Curve Fitting1、Curve Fitting 到目前为止&#xff0c;我们看到的示例都是没有数据的简单优化问题。最小二乘和非线性最小二乘分析的原始目的是对数据进行曲线拟合。 以一个…...

音质最好的骨传导蓝牙耳机有哪些,推荐几款不错的骨传导耳机

​骨传导耳机也称为“不入耳式”耳机&#xff0c;是一种通过颅骨、骨迷路、内耳淋巴液和听神经之间的信号传导&#xff0c;来达到听力保护目的的一种技术。由于它可以开放双耳&#xff0c;所以在跑步、骑行等运动时使用十分安全&#xff0c;可以避免外界的干扰。这种耳机在佩戴…...

计算机操作系统安全

操作系统安全是计算机系统安全的重要组成部分&#xff0c;目的是保护操作系统的机密性、完整性和可用性。在当前的网络环境下&#xff0c;操作系统面临着许多威胁&#xff0c;如病毒、木马、蠕虫、黑客攻击等等。为了保护操作系统的安全&#xff0c;需要采取各种措施来防范这些…...

超详细从入门到精通,pytest自动化测试框架实战教程-用例标记/执行(三)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 pytest可以通过标记…...

Java SE 基础(5) Java 环境的搭建

Java 虚拟机——JVM JVM &#xff08;Java Virtual Machine &#xff09;&#xff1a;Java虚拟机&#xff0c;简称JVM&#xff0c;是运行所有Java程序的假想计算机&#xff0c;是Java程序的运行环境&#xff0c;是Java 最具吸引力的特性之一。我们编写的Java代码&#xff0c;都…...

银行数字化转型导师坚鹏:银行对公客户数字化场景营销案例萃取

银行对公客户数字化场景营销案例萃取与行动落地课程背景&#xff1a; 很多银行存在以下问题&#xff1a;不清楚银行数字化营销与场景营销内涵&#xff1f;不知道如何开展对公客户数字化营销工作&#xff1f;不知道对公业务数字化场景营销成功案例&#xff1f; 学员收获&a…...

get和post的区别

1.用途上 get请求用来向服务器获取资源&#xff1b; post请求用来向服务器提交数据&#xff1b; 2.表单提交方式上 get请求直接将表单数据拼接到URL上&#xff0c;多个参数之间通过&符号连接&#xff1b; post请求将表单数据放到请求头或者请求体中&#xff1b; 3.传…...

Java调用Oracle存储过程

文章目录 Java调用Oracle存储过程Java调用Oracle存储过程 使用Java实现存储过程的步骤: 1、数据表、存储过程【已完成】 2、引入依赖包、数据源配置 3、Java实现【已完成】 – Oracle 创建数据表 CREATE TABLE STUDENT ( ID NUMBER (20) NOT NULL ENABLE PRIMARY KEY, NAME V…...

ubuntu如何设置qt环境变量

Qt 是一个1991年由Qt Company开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序&#xff0c;比如控制台工具和服务器。Qt是面向对象的框架&#xff0c;使用特殊的代码生成扩展&#xff08;称为元对象编译器(Meta Object Compi…...

高管对谈|揭秘 NFT 技术背后的研发方法论

有人说&#xff0c;元宇宙是未来&#xff0c;NFT 则是通往这个可能的未来的数字通行证。 经过一度热炒之后&#xff0c;NFT 逐渐回归理性的「大浪淘沙」轨迹。NXTF_&#xff08;廿四未来&#xff09;正是一家将 NFT 向实体经济靠拢并与之结合的公司。 NXTF_利用区块链技术&am…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...