【问题标题】:threadlocal variables in a servletservlet 中的线程局部变量
【发布时间】:2010-09-24 05:16:09
【问题描述】:

threadlocals 变量对于对拥有这些变量的 servlet 发出的所有请求来说都是全局的吗?

我在服务器上使用树脂。

感谢遮阳篷。

我想我可以让自己更清楚。

具体案例:

我想:

  • 在请求开始执行时初始化一个静态变量。
  • 能够以线程安全的方式在从 servlet 调用的方法的进一步执行中查询变量的值,直到请求结束执行

【问题讨论】:

    标签: java multithreading servlets concurrency thread-local


    【解决方案1】:

    简短回答:是的。
    再长一点:这就是 Spring 发挥它的魔力的方式。请参阅RequestContextHolder(通过 DocJar)。

    但需要注意 - 您必须知道何时使 ThreadLocal 无效、如何推迟到其他线程以及如何(不)与非线程本地上下文纠缠在一起。

    或者你可以只使用 Spring...

    【讨论】:

      【解决方案2】:

      我认为它们对于仅使用该特定线程发出的所有请求都是全局的。其他线程获取 thread-local 数据的其他副本。这是线程本地存储的关键点: http://en.wikipedia.org/wiki/Thread-local_storage#Java

      除非您在 servlet 配置中选中适当的选项,否则 servlet 容器将使用您的 servlet 和多个线程来并行处理请求。如此有效地,您将为为客户端提供服务的每个线程拥有单独的数据。

      如果您的 WebApplication 不是分布式的(在多个 Java 虚拟机上运行),您可以使用 ServletContext 对象在请求和线程之间存储共享数据(然后确保进行适当的锁定)。

      【讨论】:

      • 确实如此。在之前的项目中,我将用户的票证存储在他们的会话中,并创建了一个过滤器以将票证从会话传输到本地线程,以确保处理请求的线程始终可以使用用户的身份验证状态。
      【解决方案3】:

      就像 Adiel 所说,正确的方法可能是使用请求上下文(即 HttpServletRequest),而不是创建 ThreadLocal。虽然这里当然可以使用 ThreadLocal,但是如果你这样做,你必须小心清理你的线程,因为否则下一个获取线程的请求将看到与前一个请求关联的值。 (当线程的第一个请求完成时,线程将返回到池中,因此下一个请求将看到它。)当请求上下文正是为此目的而存在时,没有理由必须管理这种事情。

      【讨论】:

      • 您也可以使用 servlet 过滤器来管理 ThreadLocal,至少创建/清理会在一个地方。
      • -1 绝对有充分的理由“管理这类事情”,与仅使用一个静态 getter 相比,在您的应用程序中传递参数 1000 次之间存在差异;-)
      • 我不明白你的评论peenut。我的回答与传递大约 1000 次参数或静态 getter 无关。相反,它是关于使用 ThreadLocal 存储与 HttpServletRequest 作为 HTTP 请求的上下文之间的选择。鉴于 OP 希望绑定在请求期间持续存在,正确的上下文是 HSR(与请求一致的生命周期),而不是 ThreadLocal(在请求之间共享,因为工作线程通常是池化的)。 HSR 允许您避免清理上下文,因为它在请求结束时被丢弃。
      【解决方案4】:

      如果您使用 Servlet 3.0 可暂停请求(或 Jetty Continuations),则使用 ThreadLocal 存储请求范围信息可能会中断 使用这些 API 的多个线程处理单个请求。

      【讨论】:

        【解决方案5】:

        Threadlocal 变量总是被定义为可以全局访问,因为关键是要在可以在任何地方访问的系统周围透明地传递信息。变量的值绑定到设置它的线程,因此即使变量是全局的,它也可以根据访问它的线程具有不同的值。

        一个简单的例子是当在 servlet 中接收到请求时,将用户身份字符串分配给线程局部变量中的线程。沿着该请求的处理链的任何位置(假设它位于同一 VM 中的同一线程上),都可以通过访问此全局变量来检索身份。在处理请求时删除此值也很重要,因为线程将被放回线程池中。

        【讨论】:

          猜你喜欢
          • 2014-07-16
          • 2014-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多