ThreadLocal,Thread,ThreadLocalMap之间的关系
Thread源码
public class Thread implements Runnable {
ThreadLocal.ThreadLocalMap threadLocals = null;
}
ThreadLocal源码
public class ThreadLocal<T> {
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private Entry[] table;
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
}
}
从上面源码得出结论:
ThreadLocalMap是一个ThreadLocal的静态内部类,而ThreadLocalMap 实例里维护的是一个或者多个Entry<k,v>,每个Entry的key就是ThreadLocal实例的弱引用,value就是线程的专属变量.
Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每个线程有一个自己的ThreadLocalMap。
ThreadLocalMap有自己的独立实现,可以简单地将它的key视作ThreadLocal,value为代码中放入的值(实际上key并不是ThreadLocal本身,而是它的一个弱引用)。
每个线程在往ThreadLocal里放值的时候,都会往自己的ThreadLocalMap里存,读也是以ThreadLocal作为引用,在自己的map里找对应的key,从而实现了线程隔离。
ThreadLocalMap有点类似HashMap的结构,只是HashMap是由数组+链表实现的,而ThreadLocalMap中并没有链表结构。
我们还要注意Entry, 它的key是ThreadLocal<?> k ,继承自WeakReference, 也就是我们常说的弱引用类型。
进一步理解Thread和ThreadLocalMap的关系
Thread和ThreadLocalMap的关系,先看下边这个简单的图,可以看出Thread中的threadLocals
就是ThreadLocal中的ThreadLocalMap:
到这里应该大致能够感受到上述三者之间微妙的关系,再看一个复杂点的图:
可以看出每个thread实例都有一个ThreadLocalMap。在上图中的一个Thread的这个ThreadLocalMap中分别存放了3个Entry,默认一个ThreadLocalMap初始化了16个Entry,每一个Entry对象存放的是一个ThreadLocal变量对象。
再简单一点的说就是:一个Thread中只有一个ThreadLocalMap,一个ThreadLocalMap中可以有多个ThreadLocal对象,其中一个ThreadLocal对象对应一个ThreadLocalMap中的一个Entry(也就是说:一个Thread可以依附有多个ThreadLocal对象)。
再看一张网络上的图片,应该可以更好的理解,如下图:
这里的Map其实是ThreadLocalMap。
原文链接:https://blog.csdn.net/weixin_43314519/article/details/108188298
原文链接:https://blog.csdn.net/xlgen157387/article/details/78297568