ThreadLocal
的get()
和set()
方法会访问当前线程的ThreadLocalMap
,每个线程都有自己独立的ThreadLocalMap
实例。这个映射表以ThreadLocal
实例this作为键,与线程特定的值(value
)相关联,因此每个线程既使通过同一个ThreadLocal
实例存取值,但也是线程隔离的。
这一点可以通过ThreadLocal
的源码来进一步理解。在ThreadLocal
类中,每个线程的ThreadLocalMap
是作为Thread
类的一个字段存在的。当你对ThreadLocal
进行get()
或set()
操作时,它会先获取当前线程(Thread.currentThread()
),然后在当前线程对象内部查找或修改ThreadLocalMap
。
源码示例:
public class ThreadLocal<T> {
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
// 其他方法...
}
在上面的get()
方法示例中,this
代表当前ThreadLocal
实例,作为映射的键,但是由于getMap(t)
获取的是当前线程的ThreadLocalMap
,所以不同线程看到的映射实际上是不同的。
因此,关键点在于虽然ThreadLocal
实例是共享的,但是每个线程都有自己的ThreadLocalMap
,所以它们保存的值是独立隔离的。这就是ThreadLocal
为何能在多线程环境中保持线程局部变量独立性的原理。