ThreadLocal,ThreadLocalMap,Thread 的相互关系以及设计原理分析

1.ThreadLocal. 
真正关键的类是它的内部类ThreadLocalMap,ThreadLocal 基本上相当于一个代理,或者算是Facade模式的应用,还没想清楚这种设计的妙处。(经过分析,这种安排与弱引用的特性有关) 

2.同时,Thread类中包含一个ThreadLocalMap类型的成员变量。 

3.ThreadLocalMap的实现原理跟HashMap差不多,内部有一个Entry数组,一个Entry通常至少包括key,value, 查找时通过一定的运算规则运算Key的HASH值,来得到Entry在数组中的位置,进而得到相应的value。但是比较特殊的是, 
<1>这个Entry继承了WeakReference, 
Java代码  
  1. static class Entry extends WeakReference<ThreadLocal> {  
  2.             /** The value associated with this ThreadLocal. */  
  3.             Object value;  
  4.   
  5.             Entry(ThreadLocal k, Object v) {  
  6.                 super(k);  
  7.                 value = v;  
  8.             }  
  9.         }  

注意super(K) 这句,它实际上真正弱引用的是ThreadLocal对象。  
<2>同时它的成员的key也一直是负责管理它的ThreadLocal对象。 

好了,至此,描述一下三者之间的结构: 
ThreadLocal 负责管理ThreadLocalMap,包括插入,删除 等等,key就是ThreadLocal对象自己,同时,很重要的一点,就ThreadLocal把map存储在当前线程对象里面。看一下ThreadLocal的get,set方法就一目了然 
get(): 
Java代码  
  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.             return (T)e.value;  
  8.     }  
  9.     return setInitialValue();  
  10. }  

set(): 
Java代码  
  1. public void set(T value) {  
  2.     Thread t = Thread.currentThread();  
  3.     ThreadLocalMap map = getMap(t);  
  4.     if (map != null)  
  5.         map.set(this, value);  
  6.     else  
  7.         createMap(t, value);  
  8. }  


现在让我们站在线程的角度来看看三者之间如何互动: 
假设 TA,TB 线程, 其中TA线程分别在 LA,LB ThreadLocal对象 分别插入 VA,VB 值对象, TB 在 LA,LC 对象中插入VA,VC 值对象, 
则,TA 线程的ThreadLocalMap,存储 weak-reference(LA)-VA,wr(LB)-VB 两组值, 
TB 线程里的ThreadLocalMap存储 wr(LA)-VA,wr(LC)-VC 。 

为什么在ThreadLocalMap 中弱引用ThreadLocal对象呢,当然是从线程内存管理的角度出发的。 
使用弱引用,使得ThreadLocalMap知道ThreadLocal对象是否已经失效,一旦该对象失效,也就是成为垃圾,那么它所操控的Map里的数据也就没有用处了,因为外界再也无法访问,进而决定插除Map中相关的值对象,Entry对象的引用,来保证Map总是保持尽可能的小。 
总之,线程通过ThreadLocal 来给自己的map 添加值,删除值。同时一旦ThreadLocal本身成为垃圾,Map也能自动清除该ThreadLocal所操控的数据。 
引用

/** 
         * Heuristically scan some cells looking for stale entries. 
         * This is invoked when either a new element is added, or 
         * another stale one has been expunged. It performs a 
         * logarithmic number of scans, as a balance between no 
         * scanning (fast but retains garbage) and a number of scans 
         * proportional to number of elements, that would find all 
         * garbage but would cause some insertions to take O(n) time. 

这样,通过设计一个代理类ThreadLocal,保证了我们只需要往Map里面塞数据,无需担心清除,这是普通map做不到的

你可能感兴趣的:(thread,thread,threadLocal,threadLocal,ThreadLocalMap,ThreadLocalMap,的相互关系以及设计原理分析)