ThreadLocal详细源码解析
1.初始化是一个懒加载的过程,只有在调用get的时候才会
-
获取当前线程内部的ThreadLocalMap
-
map存在则获取当前ThreadLocal对应的value值
-
map不存在或者找不到value值,则调用setInitialValue,进行初始化
public T get() {
Thread t = Thread.currentThread();
//通过当前对象去map中寻找
ThreadLocalMap map = getMap(t);
if (map != null) {
//获取保存的entry
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
//是一个entry,如果不为空那么去entry中找到线程的局部变量
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
2. 如果不存在map,初始化ThreadLocal
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
3.如果不重写初始化方法,那么会返回空对象
protected T initialValue() {
return null;
}
4.一定要调用remove方法
必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的 ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄露等问题。
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}