是否为servlet处理的整个请求保证了一个线程?

时间:2011-01-26 23:14:34

标签: java servlets exception-handling

我遇到的情况是我使用ThreadLocal静态变量来保存一个bean,该bean在请求的生命周期中包含来自不同类的各种度量值。在过滤器中,我创建bean并将其设置在线程局部变量中,并在处理完请求后将其从同一过滤器中的线程局部变量中删除。我遇到的是包含来自其他请求的值的bean!对此的唯一解释是共享线程以同时处理多个请求。所以标题中的问题。

3 个答案:

答案 0 :(得分:6)

虽然一个线程通常会处理单个请求(肯定会谈到tomcat),但是线程可能会随着时间的推移处理多个请求但不会完成现有请求,除非使用include / forward相似。

我非常谨慎地建议你使用你的bean的所述请求的属性(setAttribute())并将其用于分析。如果你不能提供各种方法的请求......那么你就会遇到ThreadLocal [这不是那么糟糕的解决方案]。

或者,您可以发布代码如何安装/删除threadLocal bean。

请记住,您还必须管理该bean的某些内容(在请求之外不可用)。

编辑:忘了问:你是否使用try / finally调用doFilter(...)?

代码应该是那样的

installBean();
try{
  chain.doFilter(req, resp);
}finally{
 Bean b = deinstallBean();
 useTheMetrics(b);
//potentially, process exception, etc
}

答案 1 :(得分:2)

也可能是您的过滤器并不总是按照您期望的顺序调用。线程被重用来一个接一个地处理多个请求,所以如果ThreadLocal中的值没有被删除,那么当线程处理它的下一个请求时它仍然存在。

答案 2 :(得分:1)

是的,您可以假设单个线程将处理每个请求。

在处理链的其余部分后,使用finally块清除(设置为null)过滤器中的ThreadLocal。这将阻止先前请求的数据与当前请求混合。