作者回复: Tomcat会调用Web应用的代码来处理请求,可能Web应用代码阻塞在某个地方。
作者回复: 理论上:
线程数=((线程阻塞时间 + 线程忙绿时间) / 线程忙碌时间) * cpu核数
如果线程始终不阻塞,一直忙碌,会一直占用一个CPU核,因此可以直接设置 线程数=CPU核数。
但是现实中线程可能会被阻塞,比如等待IO。因此根据上面的公式确定线程数。
那怎么确定线程的忙碌时间和阻塞时间?要经过压测,在代码中埋点统计,专栏后面的调优环节会涉及到。
作者回复: 这里你误解了Connector中的线程池,这个线程池就是用来处理业务的。另外你提到线程数设的太高,会有线程切换的开销,这是对的。线程数具体设多少,根据具体业务而定,如果你的业务是IO密集型的,比如大量线程等待在数据库读写上,线程数应该设的越高。如果是CPU密集型,完全没有阻塞,设成CPU核数就行。800这个数有点高,我猜你们的应用属于IO密集型。
作者回复: 那不叫热部署,叫热加载。
热部署和热加载都不需要重启Tomcat。
作者回复: 如果在嵌入式启动,不能预测用户的行为,可能不小心起了两个线程来启动同一个Server 实例,防范于未然,再说启动阶段加个保险也没多大开销,一次性的。
作者回复: Tomcat有自己的类加载器体系,Catalina相关的类都是由
专门的类加载器catalinaLoader来加载:
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina")
Tomcat的类加载器体系会有专门的文章来详细解释。
作者回复: 最新9.x版
作者回复: 没问题
作者回复: 不管外面怎么调,加了锁这个方法就是线程安全的了
作者回复: digester应该是通过反射的方式创建Server对象的。
作者回复: 热部署和热加载有专门的一篇详细解释,简单来说就是Tomcat启动了后台线程监控项目文件的变化,一旦变了就重新加载整个应用或个别Java类。
kill -9 强杀的话,JVM钩子也没办法执行到。
作者回复: 1,对的,直接new出来
2,start方法里调了init方法
3,父容器应该是在构造函数里new了子容器
作者回复: IDE一般有disable断点的功能
作者回复: 关键就是启动了一个JVM进程去跑Tomcat的Bootstrap类。