ThreadLocal

要点

 

ThreadLocal是线程独有的线程之间隔离

ThreadLocal在整个线程上下文中都可以获得,可以避免参数的反复传递

ThreadLocal在用完之后要通过finally清除,否则如果线程复用,会遗留到下一次处理中。

 

get()

 1 public T get() {
 2         Thread t = Thread.currentThread();
 3         ThreadLocalMap map = getMap(t);
 4         if (map != null) {
 5             ThreadLocalMap.Entry e = map.getEntry(this);
 6             if (e != null) {
 7                 @SuppressWarnings("unchecked")
 8                 T result = (T)e.value;
 9                 return result;
10             }
11         }
12         return setInitialValue();
13     }

首先获得当前线程的threadLocals变量(getMap(t)),这个变量的类型是ThreadLocal.ThreadLocalMap,可以看作是一个map,存储着该线程所有ThreadLocal对象。

接下来判断如果map不为空,则拿到map中所需的ThreadLocalMap.Entry(它是ThreadLocal弱引用的子类),如果Entry也不为空,则返回Entry的value,即实际存储的对象。

如果两次判断有一个失败了,则调用setInitialValue()进行初始化。

 

小结

 

可以看出来,ThreadLocal和ThreadLocal.ThreadLocalMap.Entry其实是对应关系,而中间经过了一个ThreadLocal.ThreadLocalMap的类似map的对象。

 

ThreadLocal的精妙之处

1.ThreadLocal通过每个线程独立的ThreadLocalMap变量,实现了每个线程的Entry的独立。

2.经过这个ThreadLocalMap变量后,ThreadLocal实际转换为其弱引用类型的子类Entry,可以实现每个Entry的自动清理:每个Entry随着被get,被强引用,而当线程销毁后,只剩下弱引用,Entry便会随着下次GC被清理掉。

3.ThreadLocalMap底层是用一个Entry数组存放Entry对象的,因为如果是Map形式存放会涉及到Node指针的问题,会存在强引用,不便于GC自动清理。

 

posted @ 2020-09-08 21:40  昆梧  阅读(161)  评论(0)    收藏  举报