线程局部; 这不是和每次创建变量的副本一样吗?
我仍然对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();
....
}
如果第二个所做的只是返回变量的新副本,那么第一个与第二个有何不同?
谢谢。
I am still confused of the concept of ThreadLocal. I have read the JavaDoc, and other related questions posted around here, but the jargons used and all didn't help me much.
I kind of get the idea of ThreadLocal, that is, each thread has its own copy of the variable. So...how does this make it different from say...constructing the new variable everytime?
For example, using DateFormatter as the example:
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();
....
}
How is the first different from the second one if the all the second one does is just returning a new copy of the variable?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ThreadLocal 对象通常是静态的,这意味着它们在同一线程内的函数调用之间保留其值。
在第一个代码片段中,每次调用
convertDate
时,都会创建一个新的SimpleDateFormatter
对象。 在第二个代码段中,为每个线程创建一个SimpleDateFormatter
对象。 每次在同一线程中调用convertDate
时,get()
方法都会返回相同的对象。ThreadLocal 对象在实现线程本地存储时非常有用,这意味着为以下对象维护单独的变量实例每个线程。
ThreadLocal objects are typically static, which means that they preserve their values between function calls within the same thread.
In your first code snippet, every time
convertDate
is called, a newSimpleDateFormatter
object is created. In the second snippet, oneSimpleDateFormatter
object per thread is created. The same object is returned by theget()
method every timeconvertDate
is called within the same thread.ThreadLocal objects are useful in implementing thread-local storage, which means maintaining separate instances of variables for each thread.
ThreadLocal
有几种不同的用途。正如您的示例中所示,可以缓存构建成本高昂、线程不安全的对象。 然后可以以安全的方式使用该对象,而无需每次使用时进行构造开销。 这不一定是胜利(例如,使用更多非本地内存),但可能是。
它还可用于通过上下文参数“sleaze”到未设计为具有上下文的回调中。 或者只是为了让界面更简单。 在这种情况下,对 ThreadLocal 的规范引用可能不是静态的。 该对象也可能是故意可变的。 我不太鼓励这种技术,但有些人(例如“疯狂”鲍勃·李)喜欢它。
当您将任务分叉到多个线程时,ThreadLocal 的工作效果不太好。
InheritableThreadLocal
似乎没有什么好的用途。There are a few different uses for
ThreadLocal
.As in your example, an expensive to construct, thread-unsafe object can be cached. The object than can then be used in a safe manner without the overhead of construction every use. It's not necessarily a win (more, non-local memory is used, for instance), but it might be.
It can also be used to 'sleaze' through a context argument into a callback that isn't designed to have context. Or just to make interfaces simpler. In this case the canonical reference to the
ThreadLocal
is probably not static. The object may also be deliberately mutable. I'm not a great fan of encouraging this technique, but some people (such as "crazy" Bob Lee) like it.ThreadLocal
doesn't work so well when you fork tasks off into multiple threads.InheritableThreadLocal
appears to have no good uses.如果每次在不同的线程中调用第二个方法,则这两个示例是相同的。 在这种情况下,第一个示例更有效。
但是,如果您在同一线程中多次调用同一方法,它将缓存该线程的值,而不必每次都创建一个新对象。 (大多数与日期相关的对象都相当昂贵,在这种情况下值得这样做)在这种情况下,在线程中重用同一对象会带来很小的性能优势。
注意:线程本地对象存储在附加到线程本身的映射中。 如果线程终止,则该线程本地的所有对象都将被 GC 处理。 这就是 ThreadLocal 比大多数缓存更简单的地方。
You two examples are the same iff the second method is called in a different thread each time. In which case the first example is more efficient.
If however, you call the same method more than once in the same thread, it will cache the value for that thread and not have to create a new object each time. (Most of the object relating to dates are fairly expensive is which case it can be worth doing) In this case there is a small performance advantage in reusing the same object in a thread.
Note: the thread local objects are storing in a map attached to the Thread itself. If the thread dies, all the objects local to that thread are GCed. This is where ThreadLocal can be simpler than most caches.