Tomcat 线程池
前言
最近在压测接口,调线程池参数大小,感觉和预计的不一样。
看了看 tomcat 线程池源码 对比 JDK 线程池源码
源码
构造代码
这里是提交任务
可以看到 这里重写了 TaskQueue 类
可以看到 重写了offer方法
增加了这一行判断,如果提交的任务数没有大于最大线程数,提交的任务大于线程数,会去创建线程,而不是一味的像 JDK 线程池一样给队列里放任务。
这里返回fasle
然后继续执行原线程池方法,核心线程数满了继续下面判断,offer被 Tomcat 重写也就是上面,所以这里会返回 false,继续走下面addwork创建逻辑
addworker 里面逻辑,原jdk线程池逻辑,不用多说了吧。
线程池的并发调优
对此,tomcat是优先创建最大线程数,不是一味的往队列里放,所以,设置线程池参数,不能像 JDK 线程池一样设置,尽量优先于线程数,Tomcat 是处理业务的,而业务应当第一时间请求被处理,故而觉得 Tomcat 这么设置很合理。
既然了解了 Tomcat 线程池原理,那么我们应当设置核心线程数和最大线程数,最大线程数不能设置过多,核心线程数不能设置最小,大量请求进来,需要临时创建线程数,线程设置多了也会影响性能。
一般来说,默认核心线程数是 25,最大是 200,一般建议 500~800,具体根据硬件和业务压测设置。
Tomcat线程池扩展总结
Tomcat线程池默认实现StandardThreadExecutor。
Tomcat 线程池和 Java 原生线程池的 区别:
- 自定义了拒绝策略,Tomcat 在线程总数达到最大数时,不是立即执行拒绝策 略,而是再尝试向任务队列添加任务,添加失败后再执行拒绝策略。
- TaskQueue 重写了 LinkedBlockingQueue 的 offer 方法。只有当前线程数大 于核心线程数、小于最大线程数,并且已提交的任务个数大于当前线程数时,也就是 说线程不够用了,但是线程数又没达到极限,才会去创建新的线程。目的:在任务队 列的长度无限制的情况下,让线程池有机会创建新的线程。