【问题标题】:ThreadLocal implementation线程本地实现
【发布时间】:2010-12-02 07:09:51
【问题描述】:

参考我之前的question,再进一步,

  1. 与局部变量相比,使用 ThreadLocals 有哪些缺点
  2. 它们是如何实现的
  3. 会话变量是 ThreadLocals
  4. 是否有更多常用的 ThreadLocals 示例

【问题讨论】:

    标签: java multithreading thread-local


    【解决方案1】:

    我不确定我是否会称其为劣势,但必须非常小心地正确清理 ThreadLocals,因为只要线程存在,您放入的任何数据都会保留在那里,除非它被明确删除。这在使用线程池重用线程的环境中尤其麻烦,因此一些垃圾数据可能会附加到线程,除非它被正确清理。

    ThreadLocals 实际上被大量使用 - 主要由框架开发人员使用,因为它们允许将“上下文”附加到用户方法而不更改方法签名。例如,J2EE 中的事务管理是使用 ThreadLocals 完成的 - 对当前打开事务的引用始终附加到线程,因此当您使用数据库时,您将使用当前打开的事务自动访问它。如果没有 ThreadLocal,您将需要将这些引用作为方法参数传递。

    这种用法还有很多其他示例。我不确定您指的是哪些会话变量,但类似会话的数据通常附加到 ThreadLocal。

    关于实施 - 我不确定。我想我在某处读到它是在 JVM 中以相当低的级别实现的,以使性能非常快,因为今天有很多代码使用它。

    【讨论】:

    • “只要线程存在,你放在那里的任何数据都会保留在那里,除非它被明确删除”这似乎不是这种情况(至少在 1.6.0_26 中); Javadoc 说“只要线程活着并且 ThreadLocal 实例是可访问的”,我写的一个测试程序表明,当 ThreadLocal 变得不可访问时,可以收集 ThreadLocal 中的东西。
    【解决方案2】:
    1. 与什么相比的缺点?
    2. 作为Map<Thread,Value> -- 它实际上是附加到线程的映射,但更容易将其视为由线程键入的映射
    3. 没有
    4. ThreadLocals 很少使用,应该保持这种方式

    在我看来,应用程序开发人员使用 ThreadLocal 的唯一原因是他/她是否需要频繁使用具有(相对)高构建成本的非线程安全实用程序对象(例如 SimpleDateFormat)。即便如此,这也是一个折腾。

    【讨论】:

    • 为什么说SimpleDateFormat在建设方面成本高?
    • 您是在询问 ThreadLocal 还是在询问 SimpleDateFormat?如果您想了解后者,请查看其源代码(在 JAVA_HOME/src.zip 中提供),并将其构造函数与 StringBuilder 进行比较。
    • 您在回答中提到了“高昂的建设成本(例如 SimpleDateFormat)”。如果你能证明它在建设方面的成本是多么高,那将是有帮助的
    【解决方案3】:

    一个真实的例子:AMQP 消息传递协议允许多个多路复用逻辑连接(称为 channels)共存于一个例如TCP/IP 连接。由于某些操作会改变逻辑连接的状态,因此希望将并发消息传递操作建模为并发通道上的操作。当您的并发模型是线程化的时,您可以通过使用 ThreadLocal get() 封装通道访问并使用 initialValue() 覆盖。

    Spring 框架的上下文中,您可以使用适当的target sources 透明地使用线程本地bean。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多