01-多线程配置

news/2024/11/24 7:19:43/

如何配置springboot线程池

  • 01-springboot内部有几类线程
  • 02-springboot线程池配置标准
    • 一个问题:
      • 答案:
  • 03-springboot Tomcat线程池配置:
    • Controller请求会发生什么事情:
    • yml配置:
    • 自定义线程池配置
    • 使用自定义线程:

01-springboot内部有几类线程

我个人了解到springboot里面一般只有两种类型的线程,如果我们要自定义线程池的话,那么就应该有三种
1,springboot内置Tomcat线程池
2,GC线程,GC线程归JVM管
3,自定义线程池,我们自己显式创建的线程

02-springboot线程池配置标准

基于上述因素,可以按照以下的一般性建议进行配置:

1,线程池大小的计算:线程池大小一般建议设置为 2 * CPU核数 + 1。

2,JVM内存的计算:JVM内存的大小一般建议设置为可用内存的 1/4 到 1/2 左右,具体大小取决于应用程序的需要和系统可用内存。
3, 根据实际情况进行调整:以上建议只是一个一般性的参考,具体的配置还需要根据应用程序的类型和特性以及实际运行情况进行调整。可以通过监控工具来观察应用程序的运行情况,以便进行优化和调整。
其中需要注意:

一个问题:

线程池大小的计算:线程池大小一般建议设置为 2 * CPU核数 + 1,这个是指线程池最大线程数量吗?还是线程池的最小核心线程数量?

答案:

线程池大小一般建议设置为 2 * CPU核数 + 1 是指线程池的最大线程数量。该公式是一个经验公式,旨在帮助计算出适当的线程池大小,以提高应用程序的性能。具体线程池大小的设置还需要考虑实际的业务场景,包括处理的任务类型、任务数量、任务处理时间等因素。另外,线程池的最小核心线程数量一般设置为1,表示即使没有任务需要处理,线程池中也至少有一个线程处于运行状态,以保证线程池的可用性。

03-springboot Tomcat线程池配置:

1,注意我们请求到springboot的Controller就会用到Tomcat线程池

server:port: 8080 # 应用程序监听的端口号servlet:context-path: / # 应用程序的根路径tomcat:max-threads: 200 # tomcat线程池的最大线程数min-spare-threads: 20 # tomcat线程池的最小空闲线程数max-http-header-size: 1MB # 最大HTTP头大小accesslog:enabled: true # 是否启用Tomcat的访问日志directory: ./logs # 日志文件的存储路径prefix: access_log # 日志文件名的前缀suffix: .log # 日志文件名的后缀rotate: true # 是否启用日志文件轮转rename-on-rotate: true # 是否在轮转时重命名旧日志文件file-date-format: .yyyy-MM-dd # 日志文件名中的日期格式

Controller请求会发生什么事情:

简单描述, 因为不是正文内容:
假设你发一个请求到Spring Boot应用程序中的Controller接口,以下是Spring Boot应用程序在处理该请求时涉及到的一些关键类和方法:

  1. Spring Boot应用程序的入口类:通常情况下,Spring Boot应用程序的入口类会打上@SpringBootApplication注解,该注解包含了@ComponentScan@EnableAutoConfiguration注解,分别用于扫描Spring Bean并自动配置Spring Boot应用程序的一些特性。
  2. DispatcherServlet:DispatcherServlet是Spring MVC框架的核心组件之一,负责接收所有的HTTP请求并将其路由到适当的Controller方法中进行处理。
  3. Controller类:Controller类是你应用程序中的一部分,通常使用@RestController@Controller注解进行标注,用于处理具体的HTTP请求。
  4. Service类:Service类是Spring中用于处理业务逻辑的组件,可以使用@Service注解进行标注。
  5. Repository类:Repository类是Spring Data框架中用于访问数据库的组件,可以使用@Repository注解进行标注。
  6. Tomcat线程池:Spring Boot内置了Tomcat作为默认的Web服务器,其中的线程池默认使用SimpleAsyncTaskExecutor来处理异步请求。当请求到达应用程序时,Tomcat会为该请求分配一个线程,线程会调用Spring MVC框架的DispatcherServlet进行请求分发和处理。在处理过程中,如果有必要执行异步操作,例如发送电子邮件或执行长时间运行的任务,线程池将为该任务分配一个额外的线程,该线程将在后台处理该任务。
  7. 与请求创建和消亡相关的方法:Spring MVC框架中有一些方法用于处理HTTP请求的创建和消亡。其中,HandlerMapping接口用于映射请求URL到对应的Controller方法,HandlerAdapter接口用于调用Controller方法并将其结果转换为HTTP响应。在响应被发送到客户端之前,还有一些其他的拦截器和处理器可以对其进行修改。

需要注意的是,当处理请求的线程执行完毕时,并不会立即被GC回收,而是会被Tomcat线程池中的线程管理器重新加入线程池,等待下一次请求的到来。因此,即使线程执行完毕,该线程仍然由Tomcat线程池管理,而不是由Java虚拟机的垃圾回收器管理。

04-自定义线程池配置:

yml配置:

#线程池配置
task:pool:corePoolSize: 5maxPoolSize: 7keepAliveSeconds: 300queueCapacity: 30

自定义线程池配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;/*** 重写默认线程池配置* @author 太初*/
@Slf4j
@Configuration
@EnableAsync
//@EnableScheduling
public class OverrideDefaultThreadPoolConfig implements AsyncConfigurer {@Autowiredprivate TaskThreadPoolConfig config;@Bean("asyncTaskExecutor")@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//核心线程池大小executor.setCorePoolSize(config.getCorePoolSize());//最大线程数executor.setMaxPoolSize(config.getMaxPoolSize());//队列容量executor.setQueueCapacity(config.getQueueCapacity());//活跃时间executor.setKeepAliveSeconds(config.getKeepAliveSeconds());//线程名字前缀executor.setThreadNamePrefix("fmetro-thread-");/*当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行CallerRunsPolicy:使用此策略,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。就像是个急脾气的人,我等不到别人来做这件事就干脆自己干。AbortPolicy:该策略是线程池的默认策略。使用该策略时,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。DiscardPolicy:这个策略和AbortPolicy的slient版本,如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。DiscardOldestPolicy:丢弃最老的。也就是说如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。因为队列是队尾进,队头出,所以队头元素是最老的,因此每次都是移除对头元素后再尝试入队*/executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());executor.setWaitForTasksToCompleteOnShutdown(true);executor.initialize();return executor;}/*** 异步任务中异常处理** @return*/@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return (ex, method, params) -> {log.error("==========================" + ex.getMessage() + "=======================", ex);log.error("exception method:" + method.getName());};}
}

使用自定义线程:

@Async("asyncTaskExecutor")

http://www.ppmy.cn/news/27320.html

相关文章

【Python入门第十五天】Python字典

字典(Dictionary) 字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括号编写,拥有键和值。 实例 创建并打印字典: thisdict {"brand": "Porsche","model": "911&q…

1个寒假能学会多少网络安全技能?

现在可以看到很多标题都声称三个月内就可以转行网络安全领域,并且成为月入15K的网络工程师。那么,这个寒假的时间能学多少网络安全知识?是否能入门网络安全工程师呢? 答案是肯定的。 虽然网络完全知识是一门广泛的学科&#xff…

Mysql插入数据从指定选项中随机选择、插入时间从指定范围随机生成、Navicat使用存储过程模拟插入测试数据

场景 Navicat通过存储过程批量插入mysql数据: Navicat通过存储过程批量插入mysql数据_霸道流氓气质的博客-CSDN博客 上面使用过Navicat借助存储过程批量插入数据。但是插入数据是固定的 insert语句,如果在本地开发时需要模拟插入一些随机数据(从指定…

pip命令大全 含换源方法

目录 一、命令列表 二、通用选项列表 三、常用操作 1.使用 requirements.txt 安装包 2.生成requirements.txt文件 3.pip升级命令 4.开启向后不兼容的新功能 5.启用已弃用的功能 四、pip换源 1.临时使用pip源方法 2.永久修改方法 一、命令列表 命令说明实例install安…

「JVM 编译后话」编译器优化技术

后端编译(即时编译、提前编译)的目标时将字节码翻译成本地机器码,而难点是输出优化质量较高的机器码; 文章目录1. 优化技术概览2. 方法内联(Inlining)3. 逃逸分析(Escape Analysis)4…

C语言实现用堆解决 TOP-K 问题

目录 TopK函数实现 如何测试 完整源码 生活中我们经常能见到TopK问题,例如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 所以,TopK问题即求出一组数据中前K个最大或最小的元素,一般情况下,数据量都…

阿里云云通信风控系统的架构与实践

作者:铭杰 阿里云云通信创立于 2017 年,历经 5 年发展已经孵化出智能消息、智能语音、隐私号、号码百科等多个热门产品。目前,已成为了国内云通信市场的领头羊,在国际市场上服务范围也覆盖了 200 多个国家。随着业务的不断壮大&am…

历时半年,我终于阿里上岸了,附面经和Java非科班学习心得

个人经历 本科双非化学,跨考了电子硕士,研究生依然双非。无互联网实习,无比赛无论文。(研究生研究方向是车辆电子和楼宇自动化,有自动化和高校实训讲师相关的实习经历) 21年11开始学Java准备秋招。 阿里上…