Tomcat中的Servlet、过滤器和线程

3
在Tomcat容器中,与Servlet相关的所有过滤器和Servlet本身是否使用同一线程?即,doFilter()方法是否在与Servlet的service()方法相同的线程中运行?谢谢。
3个回答

6
我猜这个问题更多的是:我可以使用ThreadLocal对象在过滤器和servlet之间传递数据吗?如果是这样,答案是肯定的。应用服务器自己会使用ThreadLocal来跟踪安全、事务、连接和其他请求信息。
只要确保在设置ThreadLocal的代码中的finally块中清除ThreadLocal即可。
正如其他人已经指出的那样,servlet本身可能会同步或不同步,但这与线程状态的概念无关;即有多少个线程针对对象foo执行,还是我可以将状态放入线程中,并且让对象foo看到它。第二个问题的答案总是肯定的。
唯一的情况是当您使用任何异步通信时:
- 通过AsyncContext分派调用 - 混合EJB并开始使用@Asynchronous或TimerService 这些涉及应用程序服务器启动新线程,而不与原始请求线程相关联,因此任何ThreadLocal状态都不会随新线程传播。这也是为什么这些API不允许将调用者的安全性和事务上下文传播到所调用的方法中,因为调用者和方法位于不同的线程中。
高级注释:InheritableThreadLocal通常不起作用,因为异步调用通常是由服务器针对线程池而不是创建调用者线程的子线程来完成的。

4

是的,每个请求都在单个线程中执行,包括所有过滤器和目标servlet。


-1

是的,每个请求都在单个servlet实例中执行。Servlet容器接收每个请求并启动一个包含HttpServletRequest和HttpServletResponse的新线程。该线程在servlet实例的service方法中处理请求,并在service方法完成后立即销毁。


Servlet容器管理Servlet的生命周期,而不是开发人员。 - duffymo
1
服务方法不是同步的,除非servlet实现了SingleThreadModel接口,否则Tomcat将会愉快地并行运行线程来服务相同的servlet。 - nos
1
请注意,自 Servlet 2.4 推出以来已经超过5年,SingleThreadModel 已被弃用。您不应该使用它,因为这会表明设计不良 - BalusC
1
请注意,Tomcat和大多数应用服务器不会像上面描述的那样为每个请求创建/销毁线程,而是池化线程并重复使用它们。因此,请确保清除您可能设置的任何ThreadLocal状态,否则它将在以后的另一个请求中返回。 - David Blevins
非常感谢您的回答。我一直在尝试在Tomcat文档中找到这些规格,但是我没有成功。有人知道如何找到它吗? - rvelaz
这是事实上错误的,线程和servlet实例都不是每个请求创建/销毁的,它们都是被池化的。 - Szocske

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