1、set()方法:
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//得到当前线程的ThreadLocalMap
ThreadLocalMap map = getMap(t);
if (map != null)//存在赋值
map.set(this, value);
else//不存在创建
createMap(t, value);
}
//返回当前线程的ThreadLocalMap
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
从代码中可以看到ThreadLocalMap是线程Thread的一个属性。ThreadLocalMap类似于map,保证key的唯一性,key就是ThreadLocal得hash值,所以同一个线程多次set值会覆盖前面得值。
2、get()方法
public T get() {
//获取当前线程
Thread t = Thread.currentThread();
//获取线程得ThreadLocalMap属性
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;
}
}
//如果没有set值,第一次查询得时候获取默认初始化值
return setInitialValue();
}
//给ThreadLocal赋初始值
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;
}
ThreadLocal得初始值是null,可以根据一下方法修改初始值:
//通过静态方法获取有初始值得threadlocal的子类
public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
return new SuppliedThreadLocal<>(supplier);
}
//子类
static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
private final Supplier<? extends T> supplier;
SuppliedThreadLocal(Supplier<? extends T> supplier) {
this.supplier = Objects.requireNonNull(supplier);
}
@Override
protected T initialValue() {
return supplier.get();
}
}
3、内存泄漏