【问题标题】:How does my ThreadLocal gets reset every request even though we have a thread pool即使我们有一个线程池,我的 ThreadLocal 如何在每个请求中重置
【发布时间】:2015-07-11 15:03:04
【问题描述】:

我注意到了一些有趣的事情。

有人告诉我(从我读到的内容)在ThreadLocal 中保存请求范围变量是安全的(假设您无权访问请求对象并且无法使用请求属性)

嗯,它似乎有效(至少在我签入 tomcat 时)。例如即使池中有 10 个线程,线程局部变量似乎只适用于单个请求的范围。我的意思是,即使我看到相同的线程名称(假设池中有 10 个,所以在 10 个请求之后我应该看到一些重复)每个请求“神奇地”重置该线程的所有线程局部变量。

这是真的吗?

每次请求线程返回到池中时,它都会清除所有线程本地变量吗?如何?

【问题讨论】:

标签: java servlets thread-local


【解决方案1】:

以后的 tomcat 版本有一个线程本地保护机制来避免内存泄漏,特别是防止在应用程序重新部署时挂起类加载器。

TC 6.0.24 检测到它并且 7.0.6 删除了线程局部变量,如此处所述:http://wiki.apache.org/tomcat/MemoryLeakProtection

所以这对于线程/线程池来说是不正常的,而是一个 TC 特性。

【讨论】:

    【解决方案2】:

    是每次请求线程返回到池中,它都会清除所有 线程本地变量?

    似乎 Tomcat 负责打扫房间,但总的来说答案是否定的,这是导致 Glassfish 3.0.1 内存不足错误的原因之一

    在 Glassfish 3.0.1 中,例如在应用程序部署期间,一些 代码正在创建一个 ThreadLocal 变量,其中包含对某些的引用 反过来似乎又引用了许多其他的实例 对象(主要与 EJB 和 CDI 期间生成的代理类相关) 部署)。 Glassfish 似乎在 部署完成,如果线程不会有太大问题 部署应用程序终止。

    不幸的是,应用程序部署线程永远不会死掉,因为它 并非仅出于应用程序部署的目的而创建。它是 而是取自 Glassfish 线程池,预期的行为是 完成部署任务后返回池中。这意味着 ThreadLocal 引用永远不会被清理,随着时间的推移会导致 堆溢出。

    【讨论】:

      猜你喜欢
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多