java - Servlet 3 规范和 ThreadLocal

标签 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 中存储数据之外,您还有其他类似的易于访问的 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/

相关文章:

java - 字符串与 StringBuilder

.net - IronPython 中的多线程

java - Servlet/Tomcat 相对文件路径

java - 如何使用 MaxUploadSizeExceededException 避免堆栈跟踪 HTTP 状态 500 页面

java - 如何使用 Gradle 将 jar 文件添加到 libgdx 项目

Java Hadoop - Reducer 在使用 Combiner 类时多次接收同一个键的不同值

java - 一种优雅的异步解决方案,用于从 Java 中的 Vertx worker verticle 将文件从 S3 发送到客户端

C++ 超快速线程安全 rand 函数

python - Gunicorn,Django,Gevent : Spawned threads are blocking

java - java.lang.NoSuchMethodError : javax. servlet.ServletContext.getEffectiveSessionTrackingModes()Ljava/util/Set;