目录
注意:本文参考 Tomcat线程池原理_jiarus的博客-CSDN博客
详解Tomcat线程池原理及参数释义_一路奔跑1314的博客-CSDN博客_tomcat线程池
tomcat的工作原理以及简介_clean�的博客-CSDN博客_tomcat工作原理详解
Java面试题:Tomcat中BIO和NIO线程模型工作原理 - 简书
Tomcat线程池原理
线程池参数与ThreadPoolExecutor
Tomcat的线程池继承了ThreadPoolExecutor
tomcat定制了自己的Queue(重写了LinkedBlockingQueue)和ThreadFactory
最大线程数(maximumPoolSize)线程池大小有控制,可以通过参数设置
maxThreads, 最大线程数,tomcat能创建来处理请求的最大线程数
maxSpareTHreads, 最大空闲线程数,在最大空闲时间内活跃过,但现在处于空闲,若空闲时间大于最大空闲时 间,则回收,小于则继续存活,等待被调度。
minSpareTHreads,最小空闲线程数,无论如何都会存活的最小线程数
acceptCount, 最大等待队列数 ,请求并发大于tomcat线程池的处理能力,则被放入等待队列等待被处理。
maxIdleTime, 最大空闲时间,超过这个空闲时间,且线程数大于最小空闲数的,都会被回收
线程池工作原理
具体可以参考 Tomcat线程池详解 - 简书
前corePoolSize个任务入队,同时在线程池创建一个线程。
之后的任务直接放入队列,如果有空闲线程就放入队列,让空闲线程去执行,如果没有空闲线程,就拒绝入队,让新增线程。
当达到最大线程数,仍旧尝试向队列添加任务(这点和原生线程池有所不同,此时根据容量进行入队)。
到达最大容量后,添加失败,拒绝服务。
队列的offer方法
如果没有传入线程池实例,直接默认(看容量塞入)。
如果线程数=最大线程数,直接默认(看容量塞入)。
如果线程池中有空闲的线程数,直接默认(看容量塞入),让空闲的线程去执行。
如果线程池的线程数小于最大线程数,创建线程执行。(说明此时没有空闲线程,也还能够创建新的线程,因为小于最大线程数)
tomcat原理如上图。Tomcat线程池在工作的时候,实际情况是:
以上述线程池为例,一开始就创建最小空闲数的线程在池里,20个
当同一时间请求数量大于最小空闲数20,比如来了50个并发请求,那么线程池还需要创建30个线程来处理请求。这时候当请求都处理完了,持续来的请求低于50个的时候,那么当时间过了60秒,并发数还是没有达到50,那么从第50个线程开始,线程池将按照,空闲时间达到60s的,开始逐个回收,49个,48个,47个,如此回收。如果并发请求小于20个,那么线程池会回收至20个的时候,停止回收,这就是最小空闲数的作用,即使一个请求都没有,那么线程池也得保证随时都有20个。
所谓空闲回收是指:一个线程在60s的时间内,一直处于等待。那么就可以判定该线程是空闲。如果这个空闲线程是在最小空闲数以上,则会被回收。
当请求并发高于500最大空闲数的时候,线程池是会继续创建线程的,来满足特大突发性并发。当并发请求数降下之后,线程池中有空闲,那么,无论线程空闲时间是否达到60s,线程池都会进行回收至500。500以内的线程也会根据空闲时间是否大于60s来判断是否需要进行回收。
Tomcat的线程模型
下面我们看一下Tomcat支持的四种线程模式
线程模式 | 描述 |
BIO | 阻塞式IO,即Tomcat使用传统的java.io进行操作。该模式下每个请求都会创建一个线程,对性能开销大,不适合高并发场景。优点是稳定,适合连接数目小且固定架构 |
NIO | 非阻塞式IO,jdk1.4 之后实现的新IO。该模式基于多路复用选择器监测连接状态在通知线程处理,从而达到非阻塞的目的。比传统BIO能更好的支持并发性能。Tomcat 8.0之后默认采用该模式 |
APR | 全称是 Apache Portable Runtime/Apache可移植运行库),是Apache HTTP服务器的支持库。可以简单地理解为,Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作。使用需要编译安装APR 库 |
AIO | 异步非阻塞式IO,jdk1.7后之支持 。与nio不同在于不需要多路复用选择器,而是请求处理 |
BIO模式
BIO定义
BIO:同步阻塞IO(一个连接一个线程),数据的读写必须