一.方法源码
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
可以看到,和set方法有些类似,都是通过线程Thread来获取当前线程,确定ThreadLocalMap。还是先看map为空的情况,调用了setInitalValue();
看一下setInitalValue的源码
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
可以看到这里就跟set()方法类似了,首先判断map是否为空,如果不为空就调用createMap方法
,包括(新创建一个数组,设置扩容的阈值。等等操作),具体请看我上一篇文章ThreadLocal分析二:set()方法解读
但是如果map不等于空的情况下,为什么又要调用set()方法呢? 答案其实都在set()方法里面,他涉及了包括但不限于清理脏Entry(Entry不为空,但key为空的Entry)。并且还要进行refresh()等操作。所以,这就是采用弱引用的好处,当我key为null了,GC会在下一次的之后,直接就把他回收了。
下一篇我们来学习一下什么情况下ThreadLocal会内存泄漏?为什么会出现内存泄漏的情况