Tomcat线程池详解,为什么SpringBoot最大支持200并发?
Q:经典面试题,SpringBoot 应用可以同时并发处理多少请求?
A:SpringBoot 应用并发处理请求数主要由两个因素影响,使用的 Servlet容器(默认使用 Tomcat,常用的还有 jetty、undertow) 和 配置项。所以在默认配置下,SprigBoot 应用可以并发处理 200 请求。
那么这个200是怎么来的呢?SprigBoot 默认使用Tomcat,而Tomcat线程池的最大线程数就是200。到这里有朋友就有疑问了,并发数不是应该先受队列长度影响吗,难道队列长度也只有200,才会使用最大线程数吗?
Tomcat线程池
JDK 的线程池,是先使用核心线程数配置,接着使用队列长度,最后再使用最大线程配置。
Tomcat 的线程池,就是先使用核心线程数配置,再使用最大线程配置,最后才使用队列长度。
底层源码
runWorker
进入 runWorker 之后,这部分代码看起来很眼熟:

在 getTask 方法里面,可以看到关于线程池的几个关键参数:

corePoolSize,核心线程数,值为 10。
maximumPoolSize,最大线程数,值为 200。
而且基于 maximumPoolSize 这个参数,往前翻代码,会发现这个默认值就是 200:

Tomcat线程池默认队列长度:

Tomcat线程池:
核心线程数,值为 10。
最大线程数,值为 200。
队列长度,值为 Integer.MAX_VALUE。
往线程池里面提交任务的时候,会执行 execute 这个方法:

对于 Tomcat 它会调用到 executeInternal 这个方法:

这个方法里面,标号为
① 的地方,就是判断当前工作线程数是否小于核心线程数,小于则直接调用 addWorker 方法,创建线程。
② 的地方主要是调用了 offer 方法,看看队列里面是否还能继续添加任务。
如果不能继续添加,说明队列满了,则来到标号为 ③ 的地方,看看是否能执行 addWorker 方法,创建非核心线程,即启用最大线程数。
接下来看 workQueue.offer(command) 这个逻辑。如果返回 true 则表示加入到队列,返回 false 则表示启用最大线程数嘛。
workQueue.offer
这个 workQueue 是 TaskQueue,是 Tomcat 自己基于 LinkedBlockingQueue 搞的一个队列。

标号为 ① 的地方,判断了 parent 是否为 null,如果是则直接调用父类的 offer 方法。说明要启用这个逻辑,我们的 parent 不能为 null。

parent 就是 Tomcat 线程池,通过其 set 方法可以知道,是在线程池完成初始化之后,进行了赋值。也就是说,在 Tomcat 的场景下,parent 不会为空。
标号为 ② 的地方,调用了 getPoolSizeNoLock 方法:这个方法是获取当前线程池中有多个线程。所以如果这个表达式为 true:

parent.getPoolSizeNoLock() == parent.getMaximumPoolSize()
就表明当前线程池的线程数已经是配置的最大线程数了,那就调用 offer 方法,把当前请求放到到队列里面去。
标号为 ③ 的地方,是判断已经提交到线程池里面待执行或者正在执行的任务个数,是否比当前线程池的线程数还少。如果是,则说明当前线程池有空闲线程可以执行任务,则把任务放到队列里面去,就会被空闲线程给取走执行。
标号为 ④ 的地方。如果当前线程池的线程数比线程池配置的最大线程数还少,则返回 false。offer 方法返回 false,会出现什么情况?

offer返回false 则开始到上图中标号为 ③ 的地方,去尝试添加非核心线程了,也就是启用最大线程数这个配置了。
总结
JDK 的线程池,是先使用核心线程数配置,接着使用队列长度,最后再使用最大线程配置。
Tomcat 的线程池,就是先使用核心线程数配置,再使用最大线程配置,最后才使用队列长度。
那么如何调整增大SpringBoot的最大线程数呢?看到这里应该已经明白了,可以通过调整 最大线程数来 控制并发数量
面试题专栏
Java面试题专栏已上线,欢迎访问。
- 如果你不知道简历怎么写,简历项目不知道怎么包装;
- 如果简历中有些内容你不知道该不该写上去;
- 如果有些综合性问题你不知道怎么答;
那么可以私信我,我会尽我所能帮助你。
Tomcat线程池详解,为什么SpringBoot最大支持200并发?的更多相关文章
- Java线程池详解(二)
一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...
- nginx源码分析线程池详解
nginx源码分析线程池详解 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...
- 三、VIP课程:并发编程专题->01-并发编程之Executor线程池详解
01-并发编程之Executor线程池详解 线程:什么是线程&多线程 线程:线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系 ...
- Tomcat 连接数与线程池详解
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- java - jdk线程池详解
线程池参数详解 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUni ...
- Tomcat 连接池详解
(转) JDBC 连接池 org.apache.tomcat.jdbc.pool 是Apache-Commons DBCP连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Co ...
- java/android线程池详解
一,简述线程池: 线程池是如何工作的:一系列任务出现后,根据自己的线程池安排任务进行. 如图: 线程池的好处: 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销. 能有效控制线程池的最大并 ...
- Java线程池详解
一.线程池初探 所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候不是创建一个线程,而是从线程池里面获取一个可用的线程,然后执行我们的任务.线程池的关键在于它为我们管理了多 ...
- Java多线程之线程池详解
前言 在认识线程池之前,我们需要使用线程就去创建一个线程,但是我们会发现有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因 ...
随机推荐
- 【转载】 Python Pillow 和 cv2 图片 resize 速度的比较
原文地址: https://zhuanlan.zhihu.com/p/91078855 -------------------------------------------------------- ...
- 从零到一:用Go语言构建你的第一个Web服务
使用Go语言从零开始搭建一个Web服务,包括环境搭建.路由处理.中间件使用.JSON和表单数据处理等关键步骤,提供丰富的代码示例. 关注TechLead,复旦博士,分享云服务领域全维度开发技术.拥有1 ...
- 数据结构 分块 & 莫队
分块 一种优化暴力的思想. 通常是将原数据划分成适当块(一般为 \(\sqrt{n}\)),对每块数据进行预处理,进而达到比暴力更优的时间复杂度. 划分 确定块长后,一般需要开两个数组存储每一块的右边 ...
- 使用 Nuxt 3 的 defineRouteRules 进行页面级别的混合渲染
title: 使用 Nuxt 3 的 defineRouteRules 进行页面级别的混合渲染 date: 2024/8/12 updated: 2024/8/12 author: cmdragon ...
- NCP1207A笔记
uc3844d8 NCP1207A实现一个标准的电流模式结构,关断时间由峰值电流设置决定:铁芯复位检测则触发开启事件. 变压器铁芯检测:无论什么操作都会保证临界操作.因此,几乎没有一次开关接通损耗和二 ...
- 什么是ARM中的SP(堆栈)和LR?
LR是用于保存函数调用的返回地址的link register. SP是堆栈指针.堆栈通常用于在函数调用中保存"automatic"变量和上下文/参数.从概念上讲,您可以将" ...
- C# 菜单项添加复选标记
在网上查找都是说直接用菜单项的Checked属性, toolMenuItem.Checked=!toolMenuItem.Checked; 但是我用了也切换不过来. 有点晕菜了,我用的是vs2017. ...
- 编译 Qt 项目
参考:Qt 编程指南 一个最小化工作示例:qt-minimal | GitHub 源文件 main.cpp #include <QApplication> #include <QLa ...
- 【测试平台开发】——02Vue前端框架实战—router路由设计(登录页面)
一.安装vue-cli Mac系统: sudo npm install -g vue-cli 检查是否安装好: vue -V 二.创建新项目 1.打开Vue项目管理器 输入命令: vue ui 但是没 ...
- Windows平台体验StableSwarmUI-0.6.4-Beta经验版
目录 StableSwarmUI install 经验版 StableSwarmUI 配置后端 StableSwarmUI 快捷安装脚本 StableSwarmUI 安装与启动 sd_xl_base_ ...