线程是如何分配处理Servlet请求的?

57

有人可以解释一下什么是“每个请求一个线程”和“每个连接一个线程”吗?Servlets使用哪种模型?如何分配线程以处理HTTP请求?是线程/请求还是连接?

假设我想在我的ServletdoGet()方法中异步执行耗时任务,我使用Java executors启动一个新线程,这样冗长的计算就在单独的线程中完成,立即发送响应。

现在,这是否确保我已经释放了正在处理我的HttpServletRequest的线程,还是它仍然在使用,因为一个子线程仍在运行?

1个回答

61

每次请求意味着创建或从池中检索线程以服务于该请求。一个线程服务于整个请求,称为按请求分配线程。按连接分配线程则是同样的事情,只不过线程用于整个连接,可能包含多个请求,并且在请求之间也可能有很多空余时间。Servlet容器是按请求分配线程的。可能会有一些实现提供按连接分配线程,但我不知道,并且看起来这将非常浪费。

在另一个线程内创建线程并不建立任何特殊关系,在大多数情况下这样做的整个目的是让一个线程做更多的工作或终止,而另一个线程继续工作。在你的场景中,使用不同的线程来完成请求所需的工作将使响应能够立即发送,正如你所预期的那样。用于服务该请求的线程将立即可用于处理另一个请求,无论你的其他线程需要多长时间来完成。这几乎是在按请求分配线程的servlet容器中进行异步工作的方法。

注意:如果您在完整的Java EE容器中,线程可能会以使自己产生的方式来管理,这将导致产生自己的线程成为一个糟糕的想法。在这种情况下,最好向容器请求一个线程,但是一般原则仍然相同。


1
这不是在容器中执行异步工作的正确方式,尽管它可能是最简单的方法,但并不推荐。https://dev59.com/J3RB5IYBdhLWcg3wuZfo#533847 - Robin
@Robin:好主意。我加了一个关于完整JEE容器的警告。我通常是从简单的servlet容器的角度来思考的。 - Ryan Stewart
@RyanStewart,你能告诉我Servlet如何维护线程吗?我的意思是多个线程,如果我有300个请求,那么第300个线程会怎样?它什么时候执行? - Kishan Bheemajiyani
我对“In your scenario, using a different thread to do work required by a request will, as you expect, allow the response to be sent immediately.”有疑问。如果不知道最终的响应结果,怎么能立即发送响应呢?这就好比我点了一道菜,厨师马上回来,却没有任何关于我的订单的适当响应,默默地站在那里。 :) - randomcompiler
@abhishek08aug 当你发布一些长时间运行的作业时,这是非常有用的。这种端点将创建一个作业,立即返回其ID,并应该有另一个端点用于检查作业状态/结果。 - Jakub Malec
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接