【问题标题】:ThreadLocal; isn't it the same as creating a copy of the variable each time?线程本地;每次都创建一个变量的副本不一样吗?
【发布时间】:2009-05-17 01:29:25
【问题描述】:

我仍然对 ThreadLocal 的概念感到困惑。我已阅读 JavaDoc 以及此处发布的其他相关问题,但使用的行话对我没有多大帮助。

我有点理解 ThreadLocal 的概念,即每个线程都有自己的变量副本。那么...这与说...每次都构造新变量有何不同?

以 DateFormatter 为例:

public void convertDate(String date) 
{ 
    // Contruct new date formatter for every invocation of the method.
    DateFormatter df = new SimpleDateFormatter(...);
    ....
}

public void convertDate(String date) 
{ 
    // Getting date formatter from threadlocal.
    DateFormatter df = threadLocal.get();
    ....
}

如果第二个所做的只是返回变量的新副本,那么第一个与第二个有何不同?

谢谢。

【问题讨论】:

    标签: java thread-local


    【解决方案1】:

    ThreadLocal 对象通常是静态的,这意味着它们在同一线程内的函数调用之间保留其值。

    在您的第一个代码 sn-p 中,每次调用 convertDate 时,都会创建一个新的 SimpleDateFormatter 对象。在第二个 sn-p 中,每个线程创建一个 SimpleDateFormatter 对象。每次在同一线程中调用 convertDate 时,get() 方法都会返回相同的对象。

    ThreadLocal 对象在实现thread-local storage 时很有用,这意味着为每个线程维护单独的变量实例。

    【讨论】:

      【解决方案2】:

      ThreadLocal 有几种不同的用途。

      在您的示例中,可以缓存构造成本高、线程不安全的对象。然后可以以安全的方式使用该对象,而无需每次使用的构造开销。这不一定是胜利(例如,使用了更多非本地内存),但它可能是。

      它还可以用于通过上下文参数“欺骗”到并非设计为具有上下文的回调中。或者只是为了让界面更简单。在这种情况下,对ThreadLocal 的规范引用可能不是静态的。该对象也可能是故意可变的。我不太喜欢鼓励这种技术,但有些人(比如“疯狂”的 Bob Lee)喜欢它。

      ThreadLocal 在将任务分叉到多个线程时效果不佳。 InheritableThreadLocal 似乎没什么用处。

      【讨论】:

        【解决方案3】:

        如果第二个方法每次都在不同的线程中调用,那么您的两个示例是相同的。在这种情况下,第一个示例更有效。

        但是,如果您在同一个线程中多次调用同一个方法,它将缓存该线程的值,而不必每次都创建一个新对象。 (大多数与日期相关的对象都相当昂贵,在这种情况下值得这样做)在这种情况下,在线程中重用同一个对象会带来很小的性能优势。

        注意:线程本地对象存储在附加到线程本身的映射中。如果线程死亡,则该线程本地的所有对象都将被 GC。这就是 ThreadLocal 可以比大多数缓存更简单的地方。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-20
          • 2011-02-13
          • 2013-02-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多