线程不是越多越好,假如你的业务逻辑全部是计算型的(CPU密集型),不涉及到IO,并且只有一个核心。那肯定一个线程最好,多一个线程就多一点线程切换的计算,CPU不能完完全全的把计算能力放在业务计算上面,线程越多就会造成CPU利用率(用在业务计算的时间/总的时间)下降。
但是在WEB场景下,业务并不是CPU密集型任务,而是IO密集型的任务,一个线程是不合适,如果一个线程在等待数据时,把CPU的计算能力交给其他线程,这样也能充分的利用CPU资源。但是线程数量也要有个限度,一般线程数有一个公式:
最佳启动线程数 = [任务执行时间 / (任务执行时间 - IO等待时间)] * CPU内核数
超过这个数量,CPU要进行多余的线程切换从而浪费计算能力,低于这个数量,CPU要进行IO等待从而造成计算能力不饱和。总之就是要尽可能的榨取CPU的计算能力。
如果你的CPU处于饱和状态,并且没有多余的线程切换浪费,那么此时就是你服务的完美状态,如果再加大并发量,势必会造成性能上的下降。
线程多少对最高并发没有直接影响,任务计算时间才是影响最高并发数的根本原因。
当任务的执行时间减小,那么服务器每秒处理的请求就会增加,也就是说支持的并发变大。比如你在服务端只是简单的return ok;,稍微正常一点服务器上的Tomcat都能达到5000甚至10000的并发。只不过在大多数的web应用中,任务执行时间并不会太短,而且还涉及到数据库操作,所以大部分情况下Tomcat的最高并发就只有几百。
另外对于相同的任务执行时间,在不同的IO模型和线程模型中最高并发也表现的不一样。
在BIO模型中,线程数 = 链接数,并发增加会造成线程数一定程度的增加,CPU就要花费一点时间在线程切换上。
在NIO模型中,并发并不会造成线程的增加,可以维持最佳线程数,从而提高CPU的利用率,在一定程度上提高最高并发。
Tomcat已经实现了NIO模型,在7.x版本中需要配置,8.x版本使用NIO作为默认的模型。
补充:
上面的回答的不好,补充一下。
题主应该这么问,tomcat只能支持几百个并发的原因是什么?其实跟线程关系不大,暂且以1秒内服务器处理的请求数来衡量并发数,那么最大并发就是1秒内服务器最多能处理的请求数,很显然,平均单个请求处理时间越短,则最大并发越高。平均请求处理时间直接影响了最大并发的高度。而大部分情况下Tomcat处理请求的平均时间不会太短,有时还设计数据库操作,所以大部分情况下Tomcat的最高并发就只有几百。
然后线程模型会影响Tomcat处理请求的平均时间,要么是线程太少造成CPU等待而增加了平均处理时间,要么是线程太多而造成CPU要花费一定的周期来进行线程切换而延长了平均处理时间。所以合理的设置线程数能一定程度提高最大并发。
那么怎么提高最大并发呢?
思路当然是减少平均请求处理时间,比如说优化算法,动静分离,缓存,异步等等手段。