在java web当中,servlet在运行阶段,针对每个客户端的请求,都会创建一个线程,该线程调用servlet的实例?

虹一法师


具体servlet的请求处理,这个是分配给线程池线程处理的,servlet容器都这样实现,这个没什么问题。我主要来说说其它的。


线程池的作用

从其他人的回答看,都是太高看线程池本身的作用了。

线程池作为一种资源池(这里的资源就是线程了)模型,最大的优点是重复利用已经创建的线程,避免线程的反复创建和销毁带来的处理器和内存的消耗。而除此之外,它需要配合其它机制才能发挥更大的作用。

请求到达服务器后,如果线程池没有可用线程,请求会进入队列排队,如果超过队列最大阈值会被丢弃。重点来了,如果你的请求处理服务会有如数据库调用/远程服务调用的IO处理,而你用的阻塞模型,则这个线程在请求处理完成之前并不能返还到线程池供其它请求服务。这种长期占用线程的行为,会严重限制请求的并发。线程的有效利用率太低,大部分时间都在阻塞中,这个和你有没有线程池没有关系。所以要在高并发的情况下保证性能,重点是你的服务内部的使用异步IO避免阻塞。这样在你某个请求处于IO等待期间,当前线程可以返还给线程池继续提供服务。

(补充)

下面有朋友提到了请求队列,这里简单说下。

请求队列是所有服务器程序都会考虑和设计的一个机制,这样的机制实际上起缓冲层作用,避免服务器在请求过多时崩溃。以Tomcat为例,Connector中有下面几个关键配置。

acceptCount就是允许未处理请求队列的长度(backlog),默认是100,可以根据实际情况做调整。

更多的配置参见官方文档。如果有时间,会写一个Tomcat具体如何实现请求队列及它的处理文章。

请求响应

更友好的体验还要从客户端出发来考虑,如果你能缩短请求的处理时间,客户端体验是极好的,比如成都访问杭州阿里云服务器,空载来回大概40ms的时间,如果你的服务处理控制在10ms以内,请求在50ms就可以返回,是不是很舒服?当然如果是静态资源做CDN几ms就可以完成。

要缩短请求响应时间,可以从两方面入手:

1、将服务分解成多个可以并行处理的任务,这里的任务一般都会包含一个异步IO调用,然后并行执行。

2、将不影响响应结果的子任务异步处理,提前返回响应。比如推送消息,日志记录等。考虑一些极端的情况:在双11和秒杀场景,只有商品的库存处理是最核心的,这个环节处理完就可以结束本次处理,像支付这种繁琐的处理就可以延后,还有部分操作都可以放入异步队列继续处理。

将请求分解异步并行化后,实际上又会多出很多线程切换,这个时候线程池的作用就被放大了。

总结

仅仅有线程池而没有异步并行框架的支撑,线程池其实只能发挥很小的作用,在高并发情况下它必不可少,但非最核心的那个东西。我们一般的Web应用都是IO密集型的,只要保证服务内的IO都异步化,线程池只需非常少量的线程就可以应对大量并发。


迁徙de麻雀


处理http请求的线程由JAVA WEB Server来管理。比如tomcat,jetty等。通常的作法是维护一个线程池,所有请求的执行都由这个线程池中的线程来完成,如果请求超过处理能力,就会发生等待甚至崩溃的情况,因此根据业务的访问量合理的设置线程池大小是非常重要的。

以tomcat为例,下面的源代码是tomcat处理http请求初始化的代码。可以从源代码中看出,tomcat会初始化一个ThreadPoolExecutor实例,而其中的参数可以在tomcat配置文件中进行配置。


希望可以解答题主的疑问。


java老菜鸟


不是每个调用都有新线程产生,这样的话,并发量一上来不出几分钟就要挂了。主流的容器都有线程池,也就是最多同时可以接受多少连接,超过这个数的连接都要等待可用的线程才能处理。所以,在有空闲线程时不会创建新线程,就算没空闲线程也得满足条时才创建。


至亮时刻


应该不是这样的原理

线程虽然异步,可以提升cpu的运行速率,但是线程过多也会造成cpu负荷过重,比如上下文切换,比如保存线程的堆栈信息等

而一般一个网站同时访问量会达到几百万到上千万,如果线程到达这个级别,服务器会卡死


前沿小子


java web其实是一种容器框架。实现线程安全的方法,简单的说就是不要存取属性。如果设计的不好,或者真是实际的需要,要在一个servlet实例中维持些状态、连接器等信息时,你需要实现初始化、避免冲突的管理任务。


景151276607


不是的。不是创建,创建通常指给程序分配空间,在Java中所谓创建线程是指创建线程实例。而Web容器中负责请求处理的Servlt只是初次或实例实在不够分配给引用的时候才创建实例(线程对象),否则通常情况下就直接启动个线程(针对每个请求)来接受并分发请求(调用实例)。另外,一般没有人会用它保管用户的状态,所以它的实例与访问量(请求对象个数)绝不对称。对称的是线程,且分发掉请求就立刻熄灭。实例如同太阳,线程如同太阳的光线(不占地方)。另外,像地球这么大儿的地儿,一般一个太阳就够了。一个站点慢或卡跟它没关系。


分享到:


相關文章: