想清楚ThreadLocal源码的原理,那么先搞明白 ThreadLocalMap ,很关键
1.首先我们知道Thread 里面有一个ThreadLocalMap ;
public class Thread implements Runnable {
ThreadLocal.ThreadLocalMap threadLocals = null;
}
2.ThreadLocalMap里面有包含了一个成员变量Entry[] table。
static class ThreadLocalMap {
private Entry[] table;
//Entry继承了WeakReference<ThreadLocal<?>>, 说明Entry 持有一个指向ThreadLocal的弱引用。
//弱引用,就是如果一个对象只有弱引用指向它,下一次JVM垃圾回收的时候一定会被回收调。
static class Entry extends WeakReference<ThreadLocal<?>> {
//这个value就是存放我们的数据
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
///...省略部分源码
}
上面的1,2代码反应了如下关系
- 一个Thread里面包含了一个ThreadLocalMap
- 一个ThreadLocalMap包含了一个table
- table是一个Entry数组
- Entry数组有一个value存放数据,reference弱引用可以指向某个ThreadLocal
- ThreadLocalMap包含了一个Entry[] table, 其实ThreadLocalMap是底层数据结构就是一个Entry数组。
ThreadLocalMap是一个Map,Entry代表一个哈希槽。
Entry的key(键)其实就是reference, 而value(值)就是上面的value.
ThreadLocalMap存值原理:
1.就是通过Entry的 key的Hash值计算出Index
2.找到数组的Index位置,如果该位置为空就存放Entry
3.不为空则Index ++,直到找到一个空的位置存放 (这里还有一个扩容的问题,暂不讨论)
ThreadLocalMap取值原理:
1.就是通过 key的Hash值计算出Index
2.找到Index的位置Entry,再对比一下Entry的key和需要查找的key是不是相等,相等则