ThreadLocal解析

ThreadLocal结构

threadlocal.jpg

Thread/ThreadLocal/ThreadLocalMap关系

下面通过源码来分析3者之间的关系
Thread与ThreadLocalMap,Thread中包含ThreadLocalMap

public  class Thread implements Runnable {
  /* ThreadLocal values pertaining to this thread. This map is maintained  
  * by the ThreadLocal class. */  
  ThreadLocal.ThreadLocalMap threadLocals = null;
  // 省略...
}

ThreadLocal通过Thread来获取ThreadLocalMap

// java.lang.ThreadLocal#get
public T get() {  
      Thread t = Thread.currentThread();  
      ThreadLocalMap map = getMap(t);  
     if (map != null) {  
             ThreadLocalMap.Entry e = map.getEntry(this);  // this表示的是当前的ThreadLocal
             if (e != null) {  
                   @SuppressWarnings("unchecked")  
                   T result = (T)e.value;  
                   return result;  
              }  
      }  
     return setInitialValue();  //当map为null的时候初始化。
}

看一下setInitialValue方法。

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;  
}
void createMap(Thread t, T firstValue) {  // 为线程创建一个ThreadLocalMap
    t.threadLocals = new ThreadLocalMap(this, firstValue);  
}

ThreadLocalMap结构分析

源码:

static class ThreadLocalMap {  

static class Entry extends WeakReference<ThreadLocal<?>> {  
        /** The value associated with this ThreadLocal. */  
  Object value;  
  Entry(ThreadLocal<?> k, Object v) {  
      super(k);  
      value = v;  
    }  
  }
}

可以看到Entry的key是一个弱引用结构,这里需要注意的是在不需要使用ThreadLocalMap中的值时需要手动删除,如果没有删除,当JVM GC时,可能key会被回收,但是 value是一个强引用,大量的产生会导致内存泄露,所以ThreadLocal提供了remove方法。

添加新评论