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并发?的更多相关文章

  1. Java线程池详解(二)

    一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...

  2. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  3. 三、VIP课程:并发编程专题->01-并发编程之Executor线程池详解

    01-并发编程之Executor线程池详解 线程:什么是线程&多线程 线程:线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系 ...

  4. Tomcat 连接数与线程池详解

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  5. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  6. java - jdk线程池详解

    线程池参数详解 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUni ...

  7. Tomcat 连接池详解

    (转) JDBC 连接池 org.apache.tomcat.jdbc.pool 是Apache-Commons DBCP连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Co ...

  8. java/android线程池详解

    一,简述线程池: 线程池是如何工作的:一系列任务出现后,根据自己的线程池安排任务进行. 如图: 线程池的好处: 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销. 能有效控制线程池的最大并 ...

  9. Java线程池详解

    一.线程池初探 所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候不是创建一个线程,而是从线程池里面获取一个可用的线程,然后执行我们的任务.线程池的关键在于它为我们管理了多 ...

  10. Java多线程之线程池详解

    前言 在认识线程池之前,我们需要使用线程就去创建一个线程,但是我们会发现有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因 ...

随机推荐

  1. 不务正业的再次胡想——chatgpt在“智能辅助编程”外的另一个可能场景"智能论文写作辅助”

    在chatgpt4出来后震惊了很多人,但是很多人也觉得好像用处不大:可以说chatgpt4确实更加智能了,在语言对话上更加的智能,很多情况下已经很难分辨出这货是个机器人,但是现在这东西好像确实也没有太 ...

  2. xshell打开vim后颜色异常——xshell连接ubuntu打开vim后界面覆盖一层绿色

    参考原文: https://blog.csdn.net/Blank_Shen/article/details/106527312 =================================== ...

  3. 作为电脑屏幕的补光灯,到底是应该选Led灯还是荧光灯

    现在的台灯灯具市场基本被Led灯给霸占,这就无形之中要大家买台灯的时候只能选择Led等,我也是如此,手上有一款20年前上高中时候的"孩视宝"荧光灯的台灯,然后还有一款刚刚购入的Le ...

  4. (七)Redis 持久化 AOF、RDB

    Redis 一旦服务器宕机,内存中的数据将全部丢失,从后端数据库恢复这些数据,对数据库压力很大,且性能肯定比不上从 Redis 中读取,会拖慢应用程序.所以,对 Redis 来说,实现数据的 持久化 ...

  5. Jenkins配置分布式构建环境——添加固定Agent并使用JNLP启动Agent详解

    1.概述 在<Jenkins部署架构概述>这篇博文中对Jenkins部署架构进行了讲解.对于分布式架构,Jenkins包括固态Agent和动态Agent两种方案. 固定Agent(常用于虚 ...

  6. C# 菜单项添加复选标记

    在网上查找都是说直接用菜单项的Checked属性, toolMenuItem.Checked=!toolMenuItem.Checked; 但是我用了也切换不过来. 有点晕菜了,我用的是vs2017. ...

  7. idea启动项目发现端口被占用!!!导致启动不起来

    windows端口被占用 netstat -ano |findstr 端口号 任务管理器详细信息 PID排序找到刚才查到的 右键结束 原因: idea被异常终止导致tomcat没死

  8. 海康威视测速&闪速测速

    海康威视64g 闪速128g

  9. python 离线安装依赖

    步骤: 1. 访问 https://pypi.org/ 2. 搜索要下载的依赖 3. 下载tar.gz文件 4. 解压,再解压(第一次解压后的dist文件夹内tar文件需解压) 5. 解压后的文件夹内 ...

  10. Dart 2.12 现已发布

    作者 / Michael Thomsen Dart 2.12 现已发布,其中包含 健全的空安全 和 Dart FFI 的稳定版.空安全是我们最新主打的一项生产力强化功能,意在帮助您规避空值错误,以前这 ...