Tomcat扩展了原生的Java线程池,来满足Web容器高并发的需求。
简单来说,Tomcat 自定义线程池继承了 JDK 线程池 java.util.concurrent.ThreadPoolExecutor, 重写了部分方法的逻辑(主要是 execute() 方法)。Tomcat 还通过继承 LinkedBlockingQueue 重写 offer() 方法实现了自定义的队列。
这些改变使得 Tomcat 的线程池在任务量大的情况下会优先创建线程,而不是直接将不能处理的任务放到队列中。
Tomcat 自定义线程池的使用方法如下:下面我们来详细看看 Tomcat 的线程池做了哪些改变。
Tomcat 的线程池通过重写 ThreadPoolExecutor的execute() 方法实现了自己的任务处理逻辑。Tomcat 的线程池在线程总数达到最大时,不是立即执行拒绝策略,而是再尝试向自定义的任务队列添加任务,添加失败后再执行拒绝策略。那具体如何实现呢,其实很简单,我们来看一下 Tomcat 线程池的 execute()方法的核心代码。到重点的地方了!Tomcat 自定义队列TaskQueue 重写了 LinkedBlockingQueue 的 offer 方法,这是关键所在!
当提交的任务数量大于当前的线程数的时候,offer() 会返回 false,线程池会去创建新的线程,而不是等到任务队列满了之后再创建线程。TaskQueue 的 的默认值是 Integer.MAX_VALUE ,也就是说默认情况下 Tomcat 的任务队列是没有长度限制的。不过,你可以通过设置 maxQueueSize 参数来限制任务队列的长度。