一、核心原理
1. 数据存储结构
ThreadLocal 的核心在于每个线程都持有一个独立的 ThreadLocalMap。这个 Map 的 Entry 设计比较特殊:
// 每个 Thread 对象内部都有一个 ThreadLocalMap
ThreadLocal.ThreadLocalMap threadLocals = null;
// Entry 继承自 WeakReference<ThreadLocal<?>>
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value; // 强引用指向实际存储的值
Entry(ThreadLocal<?> k, Object v) {
super(k); // 弱引用指向 ThreadLocal 实例
value = v;
}
}
2. 关键设计
- 线程隔离:每个线程拥有自己的
ThreadLocalMap副本,互不干扰。 - 哈希表结构:底层使用数组 + 链表(或开放寻址法)解决冲突,JDK 8+ 主要采用开放地址法。
- 弱引用键:Entry 的 key 是
ThreadLocal实例的弱引用,允许 GC 回收未使用的 Key。 - 延迟清理:在
set/get时尝试清理过期条目,但依赖主动调用remove()更可靠。
二、源码分析
1. set() 方法流程
当我们调用 set(value) 时,实际上是往当前线程的 Map 里塞数据。逻辑上可以拆解为三步:获取 Map、查找位置、写入或替换。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value); // this 指当前 ThreadLocal 实例
} else {
createMap(t, value);
}
}
{
Entry[] tab = table;
tab.length;
key.threadLocalHashCode & (len - );
( tab[i]; e != ; e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get();
(k == key) {
e.value = value;
;
}
(k == ) {
replaceStaleEntry(key, value, i);
;
}
}
tab[i] = (key, value);
++size;
(!cleanSomeSlots(i, sz) && sz >= threshold) {
rehash();
}
}


