早上好,各位新老读者们,我是七淅(xī)。
今天和大家分享的是面试常驻嘉宾:ThreadLocal
当初鹅厂一面就有问到它,问题的答案在下面正文的第 2 点。
1. 底层结构
ThreadLocal 底层有一个默认容量为 16 的数组组成,k 是 ThreadLocal 对象的引用,v 是要放到 TheadLocal 的值
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
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);
}
数组类似为 HashMap,对哈希冲突的处理不是用链表/红黑树处理,而是使用线性探测法,即尝试顺序放到哈希冲突下标的下一个下标位置。
该数组也可以进行扩容。
2. 工作原理
一个 ThreadLocal 对象维护一个 ThreadLocalMap 内部类对象,ThreadLocalMap 对象才是存储键值的地方。
更准确的说,是 ThreadLocalMap 的 Entry 内部类是存储键值的地方
见源码 set()
,createMap()
可知。
因为一个 Thread 对象维护了一个 ThreadLocal.ThreadLocalMap 成员变量,且 ThreadLocal 设置值时,获取的 ThreadLocalMap 正是当前线程对象的 ThreadLocalMap