我今天早上刚刚了解了ThreadLocal。我读到它应该始终是最终的和静态的,如:
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
(Session是一个Hibernate会话)
我的困惑是:因为它是静态的,所以它可用于JVM中的任何线程。然而,它会保存访问它的每个线程的本地信息吗?我试图绕过这个,所以如果不清楚我会道歉。应用程序中的每个线程都可以访问相同的ThreadLocal对象,但ThreadLocal对象是否会存储每个线程的本地对象?
答案 0 :(得分:10)
是的,实例将是相同的,但是当您设置和检索时,代码会附加您使用Thread.currentThread()
设置的值,因此在访问时,可以在当前线程内访问值集使用方法set
和get
。
它很容易理解。
想象一下,每个Thread
都有一个将值与ThreadLocal
实例相关联的地图。每次在ThreadLocal
上执行获取或设置时,ThreadLocal
的实现都会获取与当前Thread
(Thread.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 Thread的ThreadLocalMap
中。 ThreadLocal
对象仅作为这些地图中的关键。
有关详细信息,请阅读ThreadLocal
和子类的JavaDoc,或者,如果您对实现很感兴趣,请阅读每个最新JDK src.zip中提供的源代码。