public
class Thread implements Runnable {
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
}
public class ThreadLocal<T> {
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}

结合上面的图看,ThreadLocal是线程(Thread)的私有变量,所以不同线程之间的threadLocal变量是隔离出来的,只能同一个线程取。Thread下面有一个成员变量threadlocals指向着ThreadLocalMap(可以看成一个hashMap),Entry对象里面的key、value分别是ThreadLocal和对应的value值。
ThreadLocal容易发生内存泄漏,当线程没有销毁,一直存在的时候,随着时间的延长,ThreadLocal里面的Entry会越来越多。(根可达性算法GC,线程(Thread)下的属性变量threadLocls无法被回收)
原来 ThreadLocal 的 ThreadLocalMap 里面存的每一个 Entry 是一个 WeakReference,WeakReference 会在 GC 的时候进行回收,回收的其实是 key,也就是弱引用的 referent, 然后 ThreadLocal 会在 set 和 get 的时候对 key 为空的 value 进行删除,所以这样就完美解决了当前线程生命周期不结束的时候,不同的 ThreadLocal 不停的追加到当前线程上面,导致内存溢出。
所以使用完毕不用后应该调用ThreadLocal.remove() 移除entry,防止应为value的强引用导致无法被gc回收。
使用方法
pulic static ThreadLocal<String> str = new ThreadLocal<>();
str.set("aaa");
str.get("aaa");
str.remove();