对ThreadLocal感到困惑

时间:2012-06-25 17:17:54

标签: java thread-local

我今天早上刚刚了解了ThreadLocal。我读到它应该始终是最终的和静态的,如:

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

(Session是一个Hibernate会话)

我的困惑是:因为它是静态的,所以它可用于JVM中的任何线程。然而,它会保存访问它的每个线程的本地信息吗?我试图绕过这个,所以如果不清楚我会道歉。应用程序中的每个线程都可以访问相同的ThreadLocal对象,但ThreadLocal对象是否会存储每个线程的本地对象?

3 个答案:

答案 0 :(得分:10)

是的,实例将是相同的,但是当您设置和检索时,代码会附加您使用Thread.currentThread()设置的值,因此在访问时,可以在当前线程内访问值集使用方法setget

它很容易理解。

想象一下,每个Thread都有一个将值与ThreadLocal实例相关联的地图。每次在ThreadLocal上执行获取或设置时,ThreadLocal的实现都会获取与当前ThreadThread.currentThread())相关联的地图并执行{{1} }或get在该地图中使用自身作为键。

示例:

set

有趣的是,ThreadLocal tl = new ThreadLocal(); tl.set(new Object()); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.put(tl, [object you gave]) Object obj = t1.get(); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.get(tl) 是层次结构的,这意味着如果您为父ThreadLocal定义了一个值,则可以从子项Thread访问它。

答案 1 :(得分:2)

对于特定问题,您始终访问ThreadLocal的同一实例,但此实例为调用get方法的每个线程返回不同的值。

这就是重点:找到对象很容易,但每个线程都有自己特定的值。因此,您可以确保两个不同的线程不会访问您的特定值。

您可以在概念上将其视为一种HashMap<Thread><V>,它始终以Thread.currentThread()作为关键字进行访问。

答案 2 :(得分:2)

因为特定于线程的值未存储在ThreadLocal对象中,而是存储在current ThreadThreadLocalMap中。 ThreadLocal对象仅作为这些地图中的关键。

有关详细信息,请阅读ThreadLocal和子类的JavaDoc,或者,如果您对实现很感兴趣,请阅读每个最新JDK src.zip中提供的源代码。