Tomcat的线程池和我们传统意义上使用的线程池稍微有些许差别,但是差别不大。他们的区别在于Tomcat线程池会先将Max Thread Size跑满,然后再去填充队列,而传统的线程池使用方式则是将队列跑满,再去扩容最大线程数。
Tomcat的线程使用在 org.apache.catalina.core.StandardThreadExecutor
类
protected void startInternal() throws LifecycleException {
this.taskqueue = new TaskQueue(this.maxQueueSize);
TaskThreadFactory tf = new TaskThreadFactory(this.namePrefix, this.daemon, this.getThreadPriority());
this.executor = new ThreadPoolExecutor(this.getMinSpareThreads(), this.getMaxThreads(), (long)this.maxIdleTime, TimeUnit.MILLISECONDS, this.taskqueue, tf);
this.executor.setThreadRenewalDelay(this.threadRenewalDelay);
if (this.prestartminSpareThreads) {
this.executor.prestartAllCoreThreads();
}
this.taskqueue.setParent(this.executor);
this.setState(LifecycleState.STARTING);
}
而跑满最大线程数的秘密则是隐藏在TaskQueue中
实现理论:都知道线程池提交任务扩容最大线程是取决于队列是否满 queue.offer
,那么只要offer失败了,那么自然就会启动最大线程数。
public boolean offer(Runnable o) {
if (this.parent == null) {
return super.offer(o);
} else if (this.parent.getPoolSize() == this.parent.getMaximumPoolSize()) {
return super.offer(o);
} else if (this.parent.getSubmittedCount() <= this.parent.getPoolSize()) {
return super.offer(o);
} else {
return this.parent.getPoolSize() < this.parent.getMaximumPoolSize() ? false : super.offer(o);
}
}