ThreadLocal 原理、使用场景及内存泄漏问题详解
核心原理
数据存储结构
ThreadLocal.ThreadLocalMap threadLocals = null;
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
关键设计
- 线程隔离:每个线程有自己的 ThreadLocalMap 副本
- 哈希表结构:使用开放地址法解决哈希冲突
- 弱引用键:Entry 的 key(ThreadLocal 实例)是弱引用
- 延迟清理:set / get 时自动清理过期条目
源码分析
set() 方法流程
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}
private void set(ThreadLocal<?> key, Object value) {
Entry[] tab = table;
int len = 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();
}