1.1 使用场景
-
1:在对象跨层传递的时候,使用ThreadLocal可以避免层次之前数据传递;
-
2:线程之间的数据隔离;
-
3:保存一些事物,数据库连接信息
1.2 实际原理
方法1:get
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();
}
方法2: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);
}
其中主要的数据容器是ThreadLocalMap,其是ThreadLocal中的内部类,是Thread的字段,其key是ThreadLocal,value为set的值。
1.3 内存泄露及防止手段
ThreadLocalMap的数据容器是:private Entry[] table;
其中具有内部类:
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
其中Map的每一个数据的key是弱引用类型,当进行GC的时候会进行回收,那么key值就变成了null值,但是ThreadLocalMap生命周期和Thread的一样,它不会回收,这时候就出现了一个现象。那就是ThreadLocalMap的key没了,但是value还在,这就造成了内存泄漏。
解决方式:在使用完之后,记得remove()。