2011-01-26 57 views
3

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

回答

6

虽然一个线程一般将处理单个请求(谈到的Tomcat,肯定的),该线程可处理随着时间的推移多个请求而不是W/O完成现有请求,除非使用包括/向前相似者。

我非常strognly建议您使用属性瓦特/你的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 
} 
+0

是的,“终于”做到了神奇。就像迈克尔和埃里克森所说的那样,在一种情况下,运行时异常并没有移除bean。谢谢。 – Murali 2011-01-26 23:39:36

+0

拇指规则(或故事的道德):如果您修改任何全局状态并打算将其撤回。使用try/finally,实际上使用try/finally需要任何清理/关闭/处理(或隐式回滚),它几乎不会导致任何性能损失(认为它是免费的:D) – bestsss 2011-01-26 23:45:32

2

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

1

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

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

相关问题