【问题标题】:Is it a good idea to use ThreadLocal as a context for data?使用 ThreadLocal 作为数据的上下文是个好主意吗?
【发布时间】:2011-02-01 17:41:50
【问题描述】:

在 Web 应用程序中使用 ThreadLocal 作为数据的上下文是个好主意吗?

【问题讨论】:

  • 为什么不用框架提供的SessionContext?
  • @Marcos,你是说 SessionContext 是 Java 提供的吗?抱歉没弄明白你指的是哪个框架...
  • 我认为他指的是 HttpSession 和/或 ServletContext(应用程序范围)。
  • @Marcos:我想你指的是javax.ejb.SessionContext。如果应用程序没有使用 Enterprise JavaBeans 怎么办?
  • SessionContext 是非常不同的东西,尤其是它仅限于单个线程(考虑 AJAX)。在某些情况下,这是需要的,在其他情况下,RequestContext 更合适。

标签: java thread-local


【解决方案1】:

这就是它的目的。但请注意删除上下文末尾的 ThreadLocal,否则您可能会在内存泄漏中运行,或者至少将未使用的数据保存太久。

ThreadLocals 也很快,你可以把它想象成一个HashMap<Thread,Object>,总是用Thread.getCurrentThread()查询。

【讨论】:

  • 那么它将是HashMap<Thread,Map<ThreadLocal,Object>>,但AFAIK它只是Thread对象中的一个内部Map<ThreadLocal,Object>
【解决方案2】:

这取决于数据的范围。 ThreadLocal 将特定于请求线程,而不特定于用户会话(每个请求,可能使用不同的请求处理线程)。因此,在请求处理完成时删除数据非常重要(这样当同一线程为他们的请求提供服务时,它不会渗入其他用户的会话)。

【讨论】:

    【解决方案3】:

    如果您使用单个线程完成请求/响应对,那么根据我的经验,它可以正常工作。然而,随着 ajax 和高性能容器的兴起,“事件驱动”的 webapps 正在流行起来。这些事件驱动模型允许将请求线程返回到它们的线程池,例如在 I/O 事件期间,线程不会被占用等待外部服务调用返回。结果,单个逻辑请求可能由多个不同的线程提供服务。事件驱动架构,再加上服务器端的 NIO,可以大大提高吞吐量。

    话虽如此,如果您的应用程序没有这种架构,我觉得这是合理的。

    如果您不熟悉此模型,请查看 Tomcat 6 的“彗星”和 Jetty 6 的 Continuations。这些是等待官方 Servlet 3.0 支持的异步 I/O 的供应商特定实现。请注意,Tomcat 7 现在声称完全兼容 3.0。

    【讨论】:

    • 它实际上不必是“事件驱动的”。如果线程空闲(等待 IO),WebSphere 7+ 将重用您的线程,然后您可以让一个线程处理两个不同的请求。我已经在两个请求之间“多路复用”工作时看到了这一点。如果您使用 threadlocals,这将导致一个非常丑陋的错误。
    【解决方案4】:

    ThreadLocal 在多线程程序中与非线程程序中的静态/全局非常相似。也就是说,使用ThreadLocal是一种可憎的行为。

    【讨论】:

    • 不,这是在函数调用层次结构的深处传递上下文信息而无需使用参数的好方法。
    • @Daniel 是的,就像单线程程序中的静态/全局一样。
    • 如果您正在运行自己的会话处理,ThreadLocal 是一个不错的选择。大多数 Web 框架都会为您做到这一点,并且可能会提供更大的灵活性(例如切换到基于 NIO 的工作线程,其中会话在线程之间切换)
    【解决方案5】:

    一般来说,我会说不。使用框架为您做到这一点。

    在 Web 应用程序的 Web 层中,使用会话上下文(或其他顶级框架特定上下文)来存储数据和请求范围内的状态。

    如果您引入业务层,它当然不应该依赖于特定的网络上下文。 springJava EE 为安全、事务和持久性作为上下文提供解决方案。

    如果你手动触摸它,你应该非常小心;它可能导致清理问题、内存泄漏和奇怪的错误......

    【讨论】:

      猜你喜欢
      • 2011-04-05
      • 2017-12-18
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      相关资源
      最近更新 更多