6

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

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

(会话是一个休眠会话)

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

4

3 回答 3

10

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

它真的很容易理解。

想象一下,每个Thread都有一个将值与ThreadLocal实例相关联的映射。每次对 a 执行 get 或 set 时ThreadLocal, 的实现ThreadLocal都会获取与当前Thread( ) 关联的映射,并使用自身作为键在该映射中Thread.currentThread()执行getor 。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它将可以从子级访问。

于 2012-06-25T17:20:37.170 回答
2

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

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

您可以(从概念上)将其视为一种HashMap<Thread><V>始终使用Thread.currentThread()as 键访问的类型。

于 2012-06-25T17:20:28.973 回答
2

因为线程特定的值不是存储在ThreadLocal对象中,而是当前 ThreadThreadLocalMap. 该ThreadLocal对象仅用作这些映射中的键。

有关详细信息,请阅读 JavaDocThreadLocal和子类,或者,如果您对实现感到好奇,请阅读每个最近的 JDK src.zip 中的源代码。

于 2012-06-25T17:34:52.360 回答