这是两个很基础的类了,大多数情况下都会用到。今天在群里有人说到这个问题,我顺便就看了下源码。
这里就简单说下这两个类的关系吧。
我们知道,在多线程环境下每个 Thread 的 ThreadLocal 是隔离的,每个 Thread 都拥有自己的 ThradLocal 副本。
换个说法就是通过同一个 ThreadLocal 在多线程的环境下可以存放和获取不同的值。
从 ThreadLocal 的 get 方法入手,看看数据是从哪里取的
public class ThreadLocal<T> {
...
/**
* 这里的 getMap 方法获取存有数据的map,并且key为当前线程
*/
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();
}
/**
* 存放数据的map对应 threadLocals 属性
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
...
}
public
class Thread implements Runnable {
...
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class.
* 这里看到上面 ThreadLocal 存放数据的map来自 Thread 的 threadLocals,并且该map由 ThreadLocal 维护
*/
ThreadLocal.ThreadLocalMap threadLocals = null;
...
}
这里我们可以梳理下这两者的关系:
1、Thread 拥有属于自己的一个map,key为 ThreadLocal,value为值
2、ThreadLocal 获取值时实际上是从当前 Thread 的map中获取(以自己为key)
这也就是为什么 ThreadLocal 能在每个 Thread 中保持一个副本,实际上数据是放在 Thread 中的。