据我所知,Servlet 3 规范引入了异步处理功能。除此之外,这意味着同一个线程可以并且将被重用于处理另一个并发的 HTTP 请求。这不是革命性的,至少对于以前与 NIO 合作过的人来说是这样。
无论如何,这导致了另一个重要的事情:没有ThreadLocal
变量作为请求数据的临时存储。因为如果同一线程突然成为不同 HTTP 请求的载体线程,请求本地数据将暴露给另一个请求。
所有这些都是我根据阅读文章的纯粹猜测,我没有时间玩任何 Servlet 3 实现(Tomcat 7、GlassFish 3.0.X 等)。
所以,问题:
- 我是否正确假设
ThreadLocal
将不再是保存请求数据的便捷方法? - 有没有人使用过任何 Servlet 3 实现并尝试使用
ThreadLocal
s 来证明上述内容? - 除了在 HTTP Session 中存储数据之外,您还有其他类似的易于访问的 hack 建议吗?
编辑:不要误会我的意思。我完全理解危险和 ThreadLocal
是一个黑客。事实上,我总是建议不要在类似的情况下使用它。然而,不管你信不信,线程上下文的使用频率远远超出你的想象。一个很好的例子是 Spring 的 OpenSessionInViewFilter
,根据它的 Javadoc:
This filter makes Hibernate Sessions available via the current thread, which will be autodetected by transaction managers.
这不是严格意义上的 ThreadLocal
(尚未检查源代码),但听起来已经令人担忧。我可以想到更多类似的场景,而丰富的 Web 框架使这种可能性更大。
简而言之,许多人都在此 hack 之上 build 了他们的沙堡,无论是否有意识。因此斯蒂芬的回答是可以理解的,但并不完全是我所追求的。我想确认是否有人真正尝试过并且能够重现失败的行为,因此这个问题可以用作其他被相同问题困住的人的引用点.
最佳答案
除非您明确要求,否则异步处理不应打扰您。
例如,如果 servlet 或请求的过滤器链中的任何过滤器未标记为 <async-supported>true</async-supported>
,则无法使请求异步。 .因此,您仍然可以对常规请求使用常规做法。
当然,如果您确实需要异步处理,则需要使用适当的做法。基本上,当请求被异步处理时,它的处理被分成几部分。这些部分不共享线程本地状态,但是,您仍然可以在每个部分中使用线程本地状态,尽管您必须手动管理各部分之间的状态。
关于java - Servlet 3 规范和 ThreadLocal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5060823/