Servlet 3规范和ThreadLocal

min*_*das 27 java multithreading servlets thread-local servlet-3.0

据我所知,Servlet 3规范引入了异步处理功能.除此之外,这意味着可以并且将重用相同的线程来处理另一个并发的HTTP请求.这不是革命性的,至少对于之前与NIO合作的人来说至少是这样.

无论如何,这导致另一个重要的事情:没有ThreadLocal变量作为请求数据的临时存储.因为如果同一个线程突然成为另一个HTTP请求的运营商线程,请求本地数据将暴露给另一个请求.

所有这些都是基于阅读文章的纯粹推测,我没有时间玩任何Servlet 3实现(Tomcat 7,GlassFish 3.0.X等).

所以,问题:

  • 我是否正确地认为ThreadLocal将不再是一个方便的黑客来保存请求数据?
  • 有没有人玩过任何Servlet 3实现并尝试使用ThreadLocals来证明上述内容?
  • 除了在HTTP Session中存储数据之外,还有其他类似的易于访问的黑客你可能会建议吗?

编辑:别误会我的意思.我完全理解危险并ThreadLocal成为黑客.事实上,我总是建议不要在类似的环境中使用它.但是,不管你信不信,线程上下文的使用频率比你想象的要频繁得多.一个很好的例子是Spring的OpenSessionInViewFilter,根据它的Javadoc:

此过滤器通过当前线程使Hibernate会话可用,该线程将由事务管理器自动检测.

这不是严格的ThreadLocal(没有检查来源),但已经听起来令人震惊.我可以想到更多类似的场景,而且丰富的Web框架使得这种情况更有可能发生.

简而言之,许多人在这个黑客的基础上建造了他们的沙堡,无论是否有意识.因此,斯蒂芬的答案是可以理解的,但并不完全是我所追求的.我想得到一个确认是否有人真正尝试能够重现失败的行为,所以这个问题可以作为被同一问题困扰的其他人的参考点.

axt*_*avt 10

异步处理不应该打扰你,除非你explcitly要求它.

例如,如果servlet或请求的过滤器链中的任何过滤器未标记,则不能使请求异步<async-supported>true</async-supported>.因此,您仍然可以使用常规做法进行常规请求.

当然,如果您确实需要异步处理,则需要使用适当的实践.基本上,当异步处理请求时,其处理被分成几部分.这些部件不共享本地线程状态,但是,你仍然可以使用本地线程状态中的每个部分,虽然你必须手动管理部件之间的状态.


Ste*_*n C 6

(警告:我没有详细阅读Servlet 3规范,因此我不能肯定地说该规范说明了你的想法.我只是假设它确实......)

我是否正确地认为ThreadLocal将不再是一个方便的黑客来保存请求数据?

使用ThreadLocal总是一种糟糕的方法,因为当工作线程完成一个请求并在另一个请求上启动时,您总是冒着信息泄漏的风险.将东西作为属性存储在ServletRequest对象中总是一个更好的主意.

现在你只是有另一个理由以"正确"的方式做到这一点.

有没有人玩过任何Servlet 3实现并尝试使用ThreadLocals来证明上述内容?

那不是正确的方法.它仅告诉您在测试的特定情况下特定实现的特定行为.你无法概括.

正确的方法是假设如果规范说它可以... 有时会发生 ...并设计你的webapp来考虑它.

(不用担心!显然,在这种情况下,默认情况下不会发生这种情况.您的webapp必须明确启用异步处理功能.如果您的代码充斥着线程本地,那么建议您不要这样做......)

除了在HTTP Session中存储数据之外,还有其他类似的易于访问的黑客你可能会建议.

不.唯一正确的答案是在ServletRequest或ServletResponse对象中存储特定于请求的数据.即使将其存储在HTTP会话中也可能是错误的,因为对于给定的会话,可能有多个请求同时处于活动状态.